How to implement Pluggable Adapter design pattern in Java - java

I know how to implement basic Adapter design pattern and also knows how C# using delegation to implement Pluggable Adapter design. But I could not find anything implemented in Java. Would you mind pointing out an example code.
Thanks in advance.

The pluggable adapter pattern is a technique for creating adapters that doesn't require making a new class for each adaptee interface you need to support.
In Java, this sort of thing is super easy, but there isn't any object involved that would actually correspond to the pluggable adapter object you might use in C#.
Many adapter target interfaces are Functional Interfaces -- interfaces that contain just one method.
When you need to pass an instance of such an interface to a client, you can easily specify an adapter using a lambda function or method reference. For example:
interface IRequired
{
String doWhatClientNeeds(int x);
}
class Client
{
public void doTheThing(IRequired target);
}
class Adaptee
{
public String adapteeMethod(int x);
}
class ClassThatNeedsAdapter
{
private final Adaptee m_whatIHave;
public String doThingWithClient(Client client)
{
// super easy lambda adapter implements IRequired.doWhatClientNeeds
client.doTheThing(x -> m_whatIHave.adapteeMethod(x));
}
public String doOtherThingWithClient(Client client)
{
// method reference implements IRequired.doWhatClientNeeds
client.doTheThing(this::_complexAdapterMethod);
}
private String _complexAdapterMethod(int x)
{
...
}
}
When the target interface has more than one method, we use an anonymous inner class:
interface IRequired
{
String clientNeed1(int x);
int clientNeed2(String x);
}
class Client
{
public void doTheThing(IRequired target);
}
class ClassThatNeedsAdapter
{
private final Adaptee m_whatIHave;
public String doThingWithClient(Client client)
{
IRequired adapter = new IRequired() {
public String clientNeed1(int x) {
return m_whatIHave.whatever(x);
}
public int clientNeed2(String x) {
return m_whatIHave.whateverElse(x);
}
};
return client.doTheThing(adapter);
}
}

Related

Visitor pattern implementation in case of source code un-availability

One of the reasons to consider the Visitor_pattern:
A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures.
Assume that you don't have the source code of third party libraries and you have added one operation on related objects.
Since you don't have object, your elements (Third party classes) can't be modified to add Visitor.
In this case, double dispatch is not possible.
So which option is generally preferred?
Option 1: Extend one more inheritance hierarchy on top of third party class and implement pattern as show in picture with double dispatch?
For a given hierarchy of Class B which extends Class A, I will add
ElementA extends A
ElementB extends B
Now ConcreteElements are derived from ElementA instead of class A.
Cons: The number of classes will grow.
Option 2: Use Visitor class a central helper class and get the work done with single dispatch.
Cons: We are not really following Visitor patter as per UML diagram.
Correct if I am wrong.
You could combine a Wrapper and Visitor to solve your problems.
Using the wrapper to add a visit method allows you to increase the usability of these objects. Of course you get the full advantages (less dependency on the legacy classes) and disadvantages (additional objects) of a wrapper.
Here's a worked-up example in JAVA (because it is pretty strict, does not do double-dispatch by itself, and I'm quite familiar with it):
1) Your legacy Objects
Assuming you have your legacy objects Legacy1 and Legacy2which you cannot change, which have specific business methods:
public final class Legacy1 {
public void someBusinessMethod1(){
...
}
}
and
public final class Legacy2 {
public void anotherBusinessMethod(){
...
}
}
2) Prepare the Wrapper
You just wrap them in a VisitableWrapper which has a visit method that takes your visitor, like:
public interface VisitableWrapper {
public void accept(Visitor visitor);
}
With the following implementations:
public class Legacy1Wrapper implements VisitableWrapper {
private final Legacy1 legacyObj;
public Legacy1Wrapper(Legacy1 original){
this.legacyObj = original;
}
public void accept(Visitor visitor){
visitor.visit(legacyObj);
}
}
and
public class Legacy2Wrapper implements VisitableWrapper {
private final Legacy2 legacyObj;
public Legacy2Wrapper(Legacy2 original){
this.legacyObj = original;
}
public void accept(Visitor visitor){
visitor.visit(legacyObj);
}
}
3) Visitor, at the ready!
Then your own Visitors can be set to visit the wrapper like so:
public interface Visitor {
public void visit(Legacy1 leg);
public void visit(Legacy2 leg);
}
With an implementation like so:
public class SomeLegacyVisitor{
public void visit(Legacy1 leg){
System.out.println("This is a Legacy1! let's do something with it!");
leg.someBusinessMethod1();
}
public void visit(Legacy2 leg){
System.out.println("Hum, this is a Legacy 2 object. Well, let's do something else.");
leg.anotherBusinessMethod();
}
}
4) Unleash the power
Finally in your code, this framework would work like this:
public class TestClass{
// Start off with some legacy objects
Legacy1 leg1 = ...
Legacy2 leg2 = ...
// Wrap all your legacy objects into a List:
List<VisitableWrapper> visitableLegacys = new ArrayList<>();
visitableLegacys.add(new Legacy1Wrapper(legacy1));
visitableLegacys.add(new Legacy2Wrapper(legacy2));
// Use any of your visitor implementations!
Visitor visitor = new SomeLegacyVisitor();
for(VisitableWrapper wrappedLegacy: visitableLegacys){
wrappedLegacy.accept(visitor);
}
}
The expected output:
This is a Legacy1! let's do something with it!
Hum, this is a Legacy 2 object. Well, let's do something else.
Drawbacks:
Quite a lot of boilerplate. Use Lombok if you develop in Java.
Quite a lot of wrapper objects instances. May or may not be a problem for you.
You need to know the specific type of the objects beforehand. This implies you know their subtype, they aren't bundles in a List. If that's the case, you have no other option but to use reflection.
There should be a possibility to add new functionality to the classes of some hierarchy, without changing the base class interface. Kinds of possible behavior should be constant, while operations for different classes should execute differently.
The Visitor Pattern allows to concentrate all that operations in one class. There might be a lot of Concrete Element classes (from the diagram), but for each of them there will be implemented visit() method in Concrete Visitor class that will define his own algorithm.
Definition and implementation of method for each subclass of Element class:
public interface Visitor {
void visit(Element element);
}
public class ConcreteVisitor implements Visitor {
public void visit(Element element) {
// implementation
}
}
The Visitor Pattern is easily extended for new operations by implementing this interface by new class with his method implementation.
The following structure encapsulates the Element class:
public lass ObjectStructure {
private Element element;
// some methods
}
This ObjectStructure class could aggregate one or several instances of Element. Presentation that Visitor acts on:
public interface Element {
void accept(Visitor visitor);
}
And implementation of accept() method in the concrete entity:
public class ConcreteElement implements Element {
public void accept(Visitor visitor) {
visitor.visit();
}
}
Using of Visitor Pattern allows to save Element hierarchy from huge logical functionality or complicated configuration.
It is desirable to add the functionality to all the classes of hierarchy while defining a new Visitor subclasses. But there could be a problem: visit() should be overriden for every hierarchy type. To avoid this it's better to define AbstractVisitor class and all leave his all visit() method bodies empty.
Conclusion: using this pattern is good when class hierarchy of type Element keeps constant. If new classes add, it usually goes to considerable changes in classes of Visitor type.
My answer is very similar to Michael von Wenckstern's, with the improvements that we have a named accept method (more like the standard pattern) and that we handle unknown concrete classes -- there's no guarantee that at some point a concrete implementation we haven't seen before won't appear on the classpath.
My visitor also allows a return value.
I've also used a more verbose name for the visit methods -- including the type in the method name, but this isn't necessary, you can call them all visit.
// these classes cannot be modified and do not have source available
class Legacy {
}
class Legacy1 extends Legacy {
}
class Legacy2 extends Legacy {
}
// this is the implementation of your visitor
abstract class LegacyVisitor<T> {
abstract T visitLegacy1(Legacy1 l);
abstract T visitLegacy2(Legacy2 l);
T accept(Legacy l) {
if (l instanceof Legacy1) {
return visitLegacy1((Legacy1)l);
} else if (l instanceof Legacy2) {
return visitLegacy2((Legacy2)l);
} else {
throw new RuntimeException("Unknown concrete Legacy subclass:" + l.getClass());
}
}
}
public class Test {
public static void main(String[] args) {
String s = new LegacyVisitor<String>() {
#Override
String visitLegacy1(Legacy1 l) {
return "It's a 1";
}
#Override
String visitLegacy2(Legacy2 l) {
return "It's a 2";
}
}.accept(new Legacy1());
System.out.println(s);
}
}
First I had to made a few assumptions about the legacy code, since you didn't provide much details about it. Let's say I need to add a new method to Legacy without reimplementing everything. This is how I'll do it:
public interface LegacyInterface {
void A();
}
public final class LegacyClass implements LegacyInterface {
#Override
public void A() {
System.out.println("Hello from A");
}
}
First extends the "contract"
public interface MyInterface extends LegacyInterface {
void B();
}
And implement it in a "decorated" way
public final class MyClass implements MyInterface {
private final LegacyInterface origin;
public MyClass(LegacyInterface origin) {
this.origin = origin;
}
#Override
public void A() {
origin.A();
}
#Override
public void B() {
System.out.println("Hello from B");
}
}
The key point is MyInterface extends LegacyInterface: this is the guarantee the implementations will benefit from both the services from the legacy code and your personnal addings.
Usage
MyInterface b = new MyClass(new LegacyClass());
I think the best approach is the Option 1: Extend one more inheritance hierarchy on top of third party class and implement the visitor pattern with double dispatch.
The problem is the number of additional classes you need, but this can be resolved with a dynamic wrapper decorator.
The Wrapper Decorator is a way to add interface implementation, methods and properties to already existing obejcts: How to implement a wrapper decorator in Java?
In this way you need your Visitor interface and put there the visit(L legacy) methods:
public interface Visitor<L> {
public void visit(L legacy);
}
In the AcceptInterceptor you can put the code for the accept method
public class AcceptInterceptor {
#RuntimeType
public static Object intercept(#This WrappedAcceptor proxy, #Argument(0) Visitor visitor) throws Exception {
visitor.visit(proxy);
}
}
The WrappedAcceptor interface defines the method to accept a visitor and to set and retrieve the wrapped object
interface WrappedAcceptor<V> {
Object getWrapped();
void setWrapped(Object wrapped);
void accept(V visitor);
}
And finally the utility code to create the Wrapper around any obect:
Class<? extends Object> proxyType = new ByteBuddy()
.subclass(legacyObject.getClass(), ConstructorStrategy.Default.IMITATE_SUPER_TYPE_PUBLIC)
.method(anyOf(WrappedAcceptor.class.getMethods())).intercept(MethodDelegation.to(AcceptInterceptor.class))
.defineField("wrapped", Object.class, Visibility.PRIVATE)
.implement(WrappedAcceptor.class).intercept(FieldAccessor.ofBeanProperty())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
WrappedAcceptor wrapper = (WrappedAcceptor) proxyType.newInstance();
wrapper.setWrapped(legacyObject);
If your library does not has accept methods you need to do it with instanceof. (Normally you do twice single-dispatching in Java to emulate double dispatching; but here we use instanceof to emulate double dispatching).
Here is the example:
interface Library {
public void get1();
public void get2();
}
public class Library1 implements Library {
public void get1() { ... }
public void get2() { ... }
}
public class Library2 implements Library {
public void get1() { ... }
public void get2() { ... }
}
interface Visitor {
default void visit(Library1 l1) {}
default void visit(Library2 l2) {}
default void visit(Library l) {
// add here instanceof for double dispatching
if (l instanceof Library1) {
visit((Library1) l);
}
else if (l instanceof Library2) {
visit((Library2) l);
}
}
}
// add extra print methods to the library
public class PrinterVisitor implements Visitor {
void visit(Library1 l1) {
System.out.println("I am library1");
}
void visit(Library2 l2) {
System.out.println("I am library2");
}
}
and now in any method you can write:
Library l = new Library1();
PrinterVisitor pv = new PrinterVisitor();
pv.visit(l);
and it will print to you "I am library1";

java 8 event listener/dispatcher using lambdas/method references - how to achieve certain things?

I'm trying to write an event engine in Java using the newly added lambdas. I would very much like it if the following code would work:
public class Test
{
public Test()
{
EventEngine.listen(EventType.THIS, self::thisEventCallback);
EventEngine.listen(EventType.THAT, self::thatEventCallback);
EventEngine.listen(EventType.OTHER, (other) -> other.doX());
}
private void thisEventCallback()
{
// do whatever here
}
private boolean thatEventCallback(SomeObject parameter)
{
return parameter.someCheckOrWhatever();
}
}
As far as I understand, I would have to define a generic empty interface, for example, public interface Listener {// nothing here}, and extend it via various other interfaces for each event type so I can specify different parameters and return types where necassary.
Obviously, that would require casting the callbacks to the specific interface inside the EventEngine's trigger method(s), but I have no problem with that.
However, before that I need to find out how to reference these private methods I have defined to the EventDispatcher.listen method. self::thisEventCallback doesn't work. Is there even a way to do this in Java 8 or is it only possible in Scala?
If not, then what would you suggest as a replacement that does not involve creating a new object for every listener/callback?
EventEngine.listen(EventType.THIS, this::thisEventCallback);
EventEngine.listen(EventType.THAT, this::thatEventCallback);
EventEngine.listen(EventType.OTHER, (other) -> other.doX());
So this instead of self.
And you need functional interfaces with one abstract method having the same signature as the callback.
public interface THISInterface {
public void thisEventCallback();
}
public interface THATInterface {
public boolean thatEventCallback(SomeObject parameter)
}
class EventEngine {
public void listen(Type t, THISInterfcace thisCallback) {
thisCallback.thisEventCallback();
}
public void listen(Type t, THATInterfcace thatCallback) {
boolean ok = thatCallback.thatEventCallback();
}
...
}
However there are already many functional interfaces predefined, which you should need to learn. For instance here, one would not need own interfaces.
class EventEngine {
public void listen(Type t, Consumer<Void> thisCallback) {
thisCallback.accept();
}
public void listen(Type t, Predicate<Void> thatCallback) {
boolean ok = thatCallback.test();
}
Whether the above is correct, I am not sure (at the moment deep in java 6 - sigh).
Instead of creating sub-interfaces adding new methods to a base interface you can define a conventional listener interface (like, say MouseListener) having multiple call-back methods and create sub-interfaces overriding all but one method with empty default methods for the sole purpose of allowing lambda implementations of the remaining single abstract method. They replace what classes like MouseAdapter did for previous Java versions (when using anonymous inner classes):
interface AllPurposeListener {// the only one our engine uses internally
void caseOne(int arg);
void caseTwo(String arg);
}
interface CaseOneListener extends AllPurposeListener {
#Override public default void caseTwo(String arg) {}
}
interface CaseTwoListener extends AllPurposeListener {
#Override public default void caseOne(int arg){}
}
// Of course, I over-simplify the engine’s listener registry here
AllPurposeListener listener;
public void listen(AllPurposeListener l) {
listener=l;
}
public void listen(CaseOneListener l) {
listener=l;
}
public void listen(CaseTwoListener l) {
listener=l;
}
private void foo(int i) { }
private void bar(String s) { }
void doRegistration() {
listen(this::foo);// register for case one
listen(this::bar);// register for case two
listen(new AllPurposeListener() { // for all cases
public void caseOne(int arg) {
}
public void caseTwo(String arg) {
}
});
}

Calling methods from objects which implement an interface

I am trying to wrap my head around interfaces, and I was hoping they were the answer to my question.
I have made plugins and mods for different games, and sometimes classes have onUpdate or onTick or other methods that are overridable.
If I make an interface with a method, and I make other classes which implement the method, and I make instances of the classes, then how can I call that method from all the objects at once?
You'll be looking at the Observer pattern or something similar. The gist of it is this: somewhere you have to keep a list (ArrayList suffices) of type "your interface". Each time a new object is created, add it to this list. Afterwards you can perform a loop on the list and call the method on every object in it.
I'll edit in a moment with a code example.
public interface IMyInterface {
void DoSomething();
}
public class MyClass : IMyInterface {
public void DoSomething() {
Console.WriteLine("I'm inside MyClass");
}
}
public class AnotherClass : IMyInterface {
public void DoSomething() {
Console.WriteLine("I'm inside AnotherClass");
}
}
public class StartUp {
private ICollection<IMyInterface> _interfaces = new Collection<IMyInterface>();
private static void Main(string[] args) {
new StartUp();
}
public StartUp() {
AddToWatchlist(new AnotherClass());
AddToWatchlist(new MyClass());
AddToWatchlist(new MyClass());
AddToWatchlist(new AnotherClass());
Notify();
Console.ReadKey();
}
private void AddToWatchlist(IMyInterface obj) {
_interfaces.Add(obj);
}
private void Notify() {
foreach (var myInterface in _interfaces) {
myInterface.DoSomething();
}
}
}
Output:
I'm inside AnotherClass
I'm inside MyClass
I'm inside MyClass
I'm inside AnotherClass
Edit: I just realized you tagged it as Java. This is written in C#, but there is no real difference other than the use of ArrayList instead of Collection.
An interface defines a service contract. In simple terms, it defines what can you do with a class.
For example, let's use a simple interface called ICount. It defines a count method, so every class implementing it will have to provide an implementation.
public interface ICount {
public int count();
}
Any class implementing ICount, should override the method and give it a behaviour:
public class Counter1 implements ICount {
//Fields, Getters, Setters
#Overide
public int count() {
//I don't wanna count, so I return 4.
return 4;
}
}
On the other hand, Counter2 has a different oppinion of what should count do:
public class Counter2 implements ICount {
int counter; //Default initialization to 0
//Fields, Getters, Setters
#Overide
public int count() {
return ++count;
}
}
Now, you have two classes implementing the same interface, so, how do you treat them equally? Simple, by using the first common class/interface they share: ICount.
ICount count1 = new Counter1();
ICount count2 = new Counter2();
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(count1);
counterList.add(count2);
Or, if you want to save some lines of code:
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(new Counter1());
counterList.add(new Counter2());
Now, counterList contains two objects of different type but with the same interface in common(ICounter) in a list containing objects that implement that interface. You can iterave over them and invoke the method count. Counter1 will return 0 while Counter2 will return a result based on how many times did you invoke count:
for(ICount current : counterList)
System.out.println(current.count());
You can't call a method from all the objects that happen to implement a certain interface at once. You wouldn't want that anyways. You can, however, use polymorphism to refer to all these objects by the interface name. For example, with
interface A { }
class B implements A { }
class C implements A { }
You can write
A b = new B();
A c = new C();
Interfaces don't work that way. They act like some kind of mask that several classes can use. For instance:
public interface Data {
public void doSomething();
}
public class SomeDataStructure implements Data {
public void doSomething()
{
// do something
}
}
public static void main(String[] args) {
Data mydataobject = new SomeDataStructure();
}
This uses the Data 'mask' that several classes can use and have certain functionality, but you can use different classes to actually implement that very functionality.
The crux would be to have a list that stores every time a class that implements the interface is instantiated. This list would have to be available at a level different that the interface and the class that implements it. In other words, the class that orchestrates or controls would have the list.
An interface is a contract that leaves the implementation to the classes that implements the interface. Classes implement the interface abide by that contract and implement the methods and not override them.
Taking the interface to be
public interface Model {
public void onUpdate();
public void onClick();
}
public class plugin implements Model {
#Override
public void onUpdate() {
System.out.println("Pluging updating");
}
#Override
public void onClick() {
System.out.println("Pluging doing click action");
}
}
Your controller class would be the one to instantiate and control the action
public class Controller {
public static void orchestrate(){
List<Model> modelList = new ArrayList<Model>();
Model pluginOne = new plugin();
Model plugTwo = new plugin();
modelList.add(pluginOne);
modelList.add(plugTwo);
for(Model model:modelList){
model.onUpdate();
model.onClick();
}
}
}
You can have another implementation called pluginTwo, instantiate it, add it to the list and call the methods specified by the interface on it.

Restrict Constructor to Sibling use - Java

This might not be possible but I am trying to create a constructor that only classes that share a super class can access, almost a reverse logic of the protected modifier. I assume there is no modifier to accomplish this directly, but knowing what I am trying to accomplish, any suggestions?
public Account extends SomeEntity {
//default public
public Account() {
}
// I am wanting this constructor to be only available to sibling classes.
// (those that share the same super class )
<modifier> Account(Element accountElement) {
}
}
public Accounts extends SomeEntity {
private List<Account> accountList;
//default public
public Accounts() {
Account newAcct = new Account(element);
//looped loading up Generic list of Account
this.accountList.add(newAcct);
}
I am working with RESTful web services and building the Objects out of XML responses, the problem is if I GET a listing of accounts, to build that into a list of Account Objects I would have to query the web service for each individual account even though I already have the information, and that seems entirely inefficient.
BUT
I don't want to give a general user, of the API I'm building, to be able to instantiate an Account Object this way. (With an Element)
There is no language construct like this. Package (=default) access is the only Java mechanism in town, as of 1.6.
I'm sure you could do nasty things with the stack, but I wouldn't recommend them.
I'd take a look at the factory pattern. You can probably play games with the access modifiers of the factory method(s) to get something close to what you want. You might also be able to play with reflection inside the factory method to get something closer to what you want than what package access gets you.
Sorry but I still don't get the point of this design. If a method is added to a class, its implementation will probably use private data to this class only, and therefore no guarantee can be made to 'sibling' classes that this data is also available for them. In other words, if your wish was granted, how would you guarantee that constructor Account(Object arg0) implementation won't use private data to Account class? (and therefore invisible to Accounts class)
It seems to me like you desire your code to provide the same interface for a single account and a list of accounts - extending SomeEntity class. That can be accomplished more elegantly with a composite pattern.
http://en.wikipedia.org/wiki/Composite_pattern
if your intent however is to provide a custom constructor that only subclasses will use, why not declare the custom constructor in SomeEntity and making this class abstract?
also, remember you can do this:
public Account() {
this(new arg0());
}
Account(Object arg0) {
}
Not sure if this helps, though.
There is a way to emulate the C++'s friend feature, and thus achieve the result you want.
Warning: This is a contrived technique that should be used only if you have no other solution!
Since no modifier does what you want in this case, the trick is to move the access restriction to another place, where modifiers apply. To do that, add a key parameter to the constructor. That key is of a class that can only be instantiated by the allowed "sibling" classes, i.e. by the subclasses of a given class.
The restriction is thus moved to the common superclass, where restraining the creation of the key is possible with the usual modifiers.
Here is an example:
public class CommonSuperClass {
public static final class Key {
private Key() {}
}
// This is the only way to create a key, and it's protected
protected final Key createKey() {
return new Key();
}
}
public class Account {
// The restricted constructor can even be public
public Account(Key key) {
// Everybody can try with null, but we're not that stupid
// Of course any RuntimeException can be thrown instead
if (key == null) throw new UnsupportedOperationException();
}
}
public class AllowedSibling extends CommonSuperClass {
public void foo() {
// I'm allowed
new Account(this.createKey());
}
}
public class DeniedClass {
public void foo() {
// This doesn't compile
new Account(new Key());
// This will throw an exception
new Account(null);
}
}
This is a very strange requisite, and I think no access modifier can do what you want. Anyway, I recommend that you just make the constructors public and document them as "for internal use only".
If you really need to limit access you can use this wordy solution:
public class Base {
protected interface Factory {
Base getInstance(Element e);
}
private static Map<Class<?>, Factory> registry = new HashMap<Class<?>, Factory>();
protected static void register(Class<?> c, Factory f) { registry.put(c, f); }
protected static <T extends Base> T create(Class<T> c, Element e) {
return (T) registry.get(c).getInstance(e);
}
}
public class Derived1 extends Base {
protected Derived1(Element e) { }
private static class Derived1Factory implements Factory {
public Derived1 getInstance(Element e) {
return new Derived1(e);
}
}
static {
register(Derived1.class, new Derived1Factory());
}
}
public class Derived2 extends Base {
protected Derived2(Element e) { }
private static class Derived2Factory implements Factory {
public Derived2 getInstance(Element e) {
return new Derived2(e);
}
}
static {
register(Derived2.class, new Derived2Factory());
}
public void method() {
Element e = null;
...
// Put some element in e
...
// This is what you were trying to do
Derived1 d1 = create(Derived1.class, e);
}
}
public class SomeEntity
protected void init(Element accountElement) {}
public class Account extends SomeEntity
public Account()
....
protected void init(Element accountElement)
....
public class Accounts extends SomeEntity
Account newAcct = new Account();
newAcct.init(element);
Here's what I would try (I have not tested this method):
<modifier> Account(Object arg) {
if (!super.getClass().isAssignableFrom(this.getClass())) {
throw new AssertionError("This constructor is only available to super classes.");
} else {
// Continue...
}
}

What is the best way to DRY up these classes, duplication in everything but constructor

So I did some refactoring and two of my classes now look exactly the same except for their constructors.
The classes wrap an API object that isn't very pretty, and add some functionality that belong at the edge of the API.
class A extends API {
public A {
this.APIOption = Option1;
this.AnotherAPIOption = Option2;
// a few more
}
public ArrayList<String> somethingTheAPIDoesntDo() {
// Do something the API doesn't provide but I use alot
}
// Other shared methods
}
class B extends API {
public B {
this.APIOption = Option3;
this.AnotherAPIOption = Option4;
// a few more
}
public ArrayList<String> somethingTheAPIDoesntDo() {
// Do something the API doesn't provide but I use alot
}
// Other shared methods
}
Does it make sense to push the common code between the two to an Abstract Base class, and have the subclasses only implement their constructors with the specialized option settings?
It makes sense on paper, but something feels weird/counterintuitive about it. Am I missing a pattern here?
Possible DRYer Solution
class A extends BetterAPIBase {
public A {
this.APIOption = Option1;
this.AnotherAPIOption = Option2;
// a few more
}
}
class B extends BetterAPIBase {
public B {
this.APIOption = Option3;
this.AnotherAPIOption = Option4;
// a few more
}
}
abstract class BetterAPIBase extends API {
public Better APIBase() {}
public ArrayList<String> somethingTheAPIDoesntDo() {
// Do something the API doesn't provide but I use alot
}
// Other methods
}
EDIT
Static Factory Pattern is nice, but I think I may also add an Interface that includes the common methods I added.
I would make the BetterAPI class also implement IBetterAPI, which would only expose the methods I added wherever I declare the instance's type as IBetterAPI.
interface IBetterAPI{
public ArrayList<String> somethingTheAPIDoesntDo();
// other methods I added in BetterAPI
}
//somewhere else:
IBetterAPI niceApi = BetterAPI.createWithOptionSetA();
niceApi.somethingTheAPIDoesntDo();
// Can't do this, nice and hidden.
niceApi.somethingBaseAPIDoes(string uglyOptions, bool adNauseum);
Wouldn't it be simpler to have one class with a parametrized (possibly private) constructor and multiple static factory methods?
class BetterAPI extends API {
private BetterAPI(APIOption option, AnotherAPIOption anotherOption) {
this.APIOption = option;
this.AnotherAPIOption = anotherOption;
}
public static BetterAPI createWithOptionSetA() {
return new BetterAPI(Option1, Option2);
}
public static BetterAPI createWithOptionSetB() {
return new BetterAPI(Option3, Option4);
}
// ...
}
The core of your problem seems to be that you can't have multiple parameterless constructors in the same class. Static factory methods offer a nice solution to this.
That's pretty close to what I'd do. Though if the "few more" makes for a lot of redundant code in the constructor, I'd write:
abstract class BetterAPIBase extends API {
public BetterAPIBase(String APIOption, int AnotherAPIOption, ... more ...) {
this.APIOption=APIOption;
this.AnotherAPIOption=AnotherAPIOption;
// a few more
}
public ArrayList<String> somethingTheAPIDoesntDo() {
// Do something the API doesn't provide but I use alot
}
// Other methods
}
class A extends BetterAPIBase {
public A {
super(Option1, Option2, ... more ...);
}
}
class B extends BetterAPIBase {
public B {
super(Option3, Option4, ... more ...);
}
}
Of course if any of the option values are the same then they wouldn't need to be passed, which is where real redundancy elimination would come.

Categories