Skip to content

JonathanxD/AdapterHelper

Repository files navigation

AdapterHelper

Replacement of old, verbose and useless Adapter project.

This project is intended to help adapter pattern implementation.

Use cases

Adapter pattern is used to adapt a type to another without losing capabilities and remaining linked to instance.

For example, if you have 2 platforms, and each platform defines an type called Person and you want to treat these types with same code:

public class Lib1_Person {
    private final String name;
    private final int age;
    
    // ...
}

public class Lib2_Person {
    private final String name;
    private final int age;
    private final List<Lib2_Person> parents;
    // ...
}

public class PersonProcessor {
    
    public void process(Lib1_Person person) {
        // ...
    }
    
    public void process(Lib2_Person person) {
        // ...
    }
    
}

There are various ways to solve this problem:

  • Destruct these instances and delegate call to another method. (good, as far you don't need to manipulate other properties and does not call it from many places)
  • Process every type in a method. (Bad, too bad)
  • Create a proxy and call methods of other type. (Works, is really good and time saver, but at the same time, is hard to maintain if the types have different signatures) Internally cached
  • Creates an Adapter and cache or instantiate on every call. (Good, and the best way)

Example: See ReadmeExamples.java.

AdapterHelper provide utilities to working with the last approach and reducing the boilerplate code.

Adapter Management

AdapterManager is the class used to register, get and use adapters and converters. This class also provides a weak cache for Adapter instances.

Adapter

The base class of all adapter classes, commonly adapter interfaces extend it and AdapterImplGen generates the concrete implementation.

AdapterBase

More simple adapter, this only have a original instance property, this is commonly used in places where AdapterManager does not have to be provided (simple adapters).

Converter

The converter of data types, like String to Integer.

AdapterSpecification

Class used to store specification of Adapter, this class is used for registration and internally used to fetch Adapters.

AdapterImplGen (Requires Kores, Kores-BytecodeWriter and KoresGenUtil)

Utility class used to generate implementation of Adapter interfaces (explained later).

@Field & @Fields (generation)

Used to generate additional fields in implementations generated by AdapterImplGen

Storage and WeakAdapteeStorage

Used to store dynamical fields (alternative for @Field)

StrongCache

Used to Strong cache adapter instances.

Simple adapter using AdapterHelper

There are multiple ways to create adapters using AdapterHelper utilities, the mostly used (at least by me), is the combination of interface adapter and AdapterImplGen, this keeps extensibility and you don't need to write concrete implementation, examples:

Readme.java.

Converters

Converters are used to convert data types. Converted objects are not cached like Adapters and does not have access to AdapterManager because they should not access it. Converters are commonly singleton.

Example:

Readme.java.

Adapters with additional fields. (generation)

Sometimes you need to store additional data, but the field does not exists in target class, to solve this problem you can use @Field annotation to include fields in your adapter generated class (using AdapterImplGen) or add fields to your concrete adapter implementation (make sure to annotate your adapter with StrongCache, I will explain it later). You can also use WeakAdapteeStorage (or your own implementation of IStorage) to store dynamic fields in a map.

StrongCache is required because by default, AdapterManager caches adapters weakly, this means that if it is not referenced in the code, it will be collected by the gc, this causes field values to be lost, to avoid this behavior, you should annotate your adapter class (or any interface or sub-class) with StrongCache, but this should be used with care, because it will prevent GC from collecting references, which can lead to memory leaks, to remove adapters from cache you should use uncacheStrong (or uncacheAllStrong if you need to remove all adapters).

Obs: As Field and Fields are annotated with StrongCache, all classes annotated with them will be strong cached

Also AdapterHelper have WeakAdapteeStorage which can be used to store fields by adaptee instance instead of storing in Adapter class in fields, because of weak nature, if adaptee is collected, all field values reference are lost.

Obs: WeakAdapteeStorage class is not singleton, but have an GLOBAL instance, and each AdapterManager has its own Storage instance, which is implemented by WeakAdapteeStorage and is visible to use.

Example: DynamicFieldTest.java.

Concrete Adapters

You are free to use concrete adapters and register them in AdapterManager, if you have only concrete adapters, you don't need Kores, Kores-BytecodeWriter, KoresProxy nor KoresGenUtil.

Okay, it is not true anymore, there is no guarantee that AdapterHelper works without Kores, but I plan to separate the project in two modules, a basic module that does not require Kores and a full module that requires. This is not true anymore because even if you don't have Kores, the classes that depends on Kores exists, some frameworks may not like that, and others projects may use these classes.

Adapter collections

Provides collections which handles and delegates adaptation to a wrapped instance, this means that if you adapt OldPerson to Person and them create a List of Person from a List of OldPerson (using AdapterManager), all changes made on both Lists will be reflected on each other.

Currently, we only implemented Collection, List, Set and Map. You can also open an issue to request more implementations or send a pull request of implementation of other classes (and we will accept happily). But we only accepts implementations on top of Java or Kotlin classes.

About

Adapter management helper.

Resources

License

Stars

Watchers

Forks

Packages

No packages published