How to avoid duplicate code while using Strategy Design Pattern? - java

I am new to design patterns and thinking about using Strategy design pattern for implementing code in my backend service. However, the Strategies are having duplicate code. I have the following classes:-
class StrategyA implements Strategy {
private Helperclass1 helperclass1;
private Helperclass2 helperclass2;
private Daoclass dao;
public void execute(Object obj) {
updatedObj = helperclass1.method(obj);
updatedObj = helperclass2.method2(updatedObj);
updatedObj = updateObj(updatedObj);
dao.update(updatedObj);
}
private Object updateObj(Object obj) {
//update obj & return;
}
}
class StrategyB implements Strategy {
private Helperclass1 helperclass1;
private Helperclass2 helperclass2;
private Daoclass dao;
public void execute(Object obj) {
updatedObj = helperclass1.method(obj);
updatedObj = helperclass2.method2(updatedObj);
dao.update(updatedObj);
}
}
class StrategyC implements Strategy {
private Helperclass1 helperclass1;
private Daoclass dao;
public void execute(Object obj) {
updatedObj = helperclass1.method(obj);
dao.update(updatedObj);
}
}
What should I do to remove duplicate code from Strategy pattern? I am considering not using the design pattern to avoid code duplication. Can anyone suggest a better design pattern for this usecase?
I read about some similar situations and found that Command or Template patterns may be considered as an alternative (link:What pattern to use with a Strategy Pattern to avoid duplicate code inside Concrete Strategies?). However I am not sure how I can effectively use these patterns for my use-case.

You can make one general strategy that executes multiple strategies. Like event handling. The idea:
interface Strategy
{
Object execute(Object obj);
}
class MultiStrategy implements Strategy
{
private Strategy[] strategies;
public Object execute(Object obj)
{
foreach (Strategy s : strategies)
obj = s.execute(obj);
return obj;
}
}
class Strategy1 implements Strategy
{
private Helperclass1 helperclass1;
public Object execute(Object obj)
{
return helperclass1.method1(obj);
}
}
class Strategy2 implements Strategy
{
private Helperclass1 helperclass2;
public Object execute(Object obj)
{
return helperclass2.method2(obj);
}
}
And the usage would be kinda like:
Strategy s = new MultiStrategy(new Strategy[]
{
new Strategy1(helper1),
new Strategy2(helper2),
});
In my example the strategies 1 and 2 and in fact adapters, but that's also a common use case. The benefit of this is that you can use the same code of MultiStrategy for any number of substeps, or even combine multiple multi strategies under the Strategy interface to make trees of strategies. Note though, that this MultiStrategy is another pattern in and of itself, just using a single-layer strategy is not enough to clean this up in your case. I don't remember they call it officially, but I guess you can call it event handling.

You can eliminate duplicate code through inheritance, if you can factor the common code out.

Related

Good chain of builder pattern

i have a complex business object like so
public class BusinessObject {
public Team1Object object1;
public Team2Object object2;
public String debug;
...
}
I am using slight modification of chain of responsibility pattern to build the above object.
Here is my interface
public interface BusinessObjectAppender {
public void append(BusinessObjectBuilder businessObject, Context someApplicationContext);
}
Now teams can comes and write their appenders. like so
public class Team1ObjectAppender implements BusinessObjectAppender {
public void append(BusinessObjectBuilder businessObject, Context someApplicationContext) {
Team1Object object1 = somehowComputeObject1();
businessObject.object1(object1)
}
}
public class Team2Appender implements BusinessObjectAppender {
public void append(BusinessObjectBuilder businessObject, Context someApplicationContext) {
Team2Object object2 = somehowComputeObject2();
businessObject.object2(object2)
}
}
By using this approach, In case of complex object construction the logic does not bloat up.
But It also has issues like
There are no guardrails around Team1 messing up with another team's object or being dependent on another team's data. Apart from code reviews.
The cases where BusinessObject is polymorphic, Once i have created builder of 1 type it is not possible to change it in appenders.
Question
Is this right pattern to do?
what are other ways to achieve the same thing? (creating complex objects in scalable, understandable way)
If you plan to use a builder pattern, then following separation of concerns, I would prefer to use a separate class for the BusinessObject object by employing a BusinessObjectBuilder builder pattern object. In order to access the builder pattern object from the relevant domain/business object, you can then (optionally, and I would recommend if appropriate, to) add a public static create() method to instantiate both a builder object and an encapsulated business object to build. I personally prefer the fluent style of builder objects, as the methods can be chained together and it makes writing the code so much easier.
As you are concerned about the complexity of building a Team1Object field and Team2Object field as separate concerns, I would think that what you are looking for is not a flat builder pattern, but instead facades of a builder pattern, or builder facets. In order to use facades of a builder, you would use a common builder base class and builder facade classes derived from the base class.
The base class, upon instantiation will create a simple BusinessObject and provide a method to build each field, including, by incorporating the fluent facade builders. The fluent facade builders will build only one part of the object parcel, the part of which may be complex in and of itself and could therefore be a separate concern from the overall building of the object as a whole.
As in all fluent builder classes, the return type is the same as the fluent builder (or fluent facade builder) class. Consider the following modifications:
public class BusinessObject {
internal BusinessObject() {
// Default constructor should exist
// but only needs to be visible at the
// BusinessObjectBuilder scope.
// use whatever access modifier you would
// prefer, however, based on needs,
// internal or public is appropriate.
// in C++, use `friend BusinessObjectBuilder`
}
public Team1Object object1;
public Team2Object object2;
public String debug;
...
public static BusinessObjectBuilder create() {
return new BusinessObjectBuilder();
}
}
public class BusinessObjectBuilder {
protected BusinessObject bObject; // the object we will build
internal BusinessObjectBuilder() {
// A default constructor, again minimally visible
// to BusinessObject; internal or public is good here.
// Needs to create a basic BusinessObject.
bObject = new BusinessObject();
}
public BusinessObjectBuilder debug(String debugString) {
// Sets BusinessObject.debug
this.bObject.debug += debugString + "\n";
// Then returns the BusinessObjectBuilder.
// Every method should return this except the facade methods
// and the build method.
return this;
}
public Team1ObjectBuilder team1Object() {
// Returns the Team1Object builder facet.
return new Team1ObjectBuilder(this.bObject);
}
public Team2ObjectBuilder team2Object() {
// Returns the Team2Object builder facet.
return new Team1ObjectBuilder(this.bObject);
}
public BusinessObject build() {
// Technically, it's already built at this point. Return it.
return this.bObject;
}
}
public class Team1ObjectBuilder extends BusinessObjectBuilder {
private BusinessObject bObject; // the object we will build
internal Team1ObjectBuilder(BusinessObject bObject) {
// This time we copy the object we were building
this.bObject = bObject;
}
private Team1Object somehowComputeObject1() {
// pour on the magic
return new Team1Object();
}
public Team1ObjectBuilder append(Context someApplicationContext) {
this.bObject.object1 = somehowComputeObject1();
}
}
public class Team2ObjectBuilder extends BusinessObjectBuilder {
private BusinessObject bObject; // the object we will build
internal Team2ObjectBuilder(BusinessObject bObject) {
// Again we copy the object we were building
this.bObject = bObject;
}
private Team2Object somehowComputeObject2() {
// pour on the magic
return new Team2Object();
}
public Team2ObjectBuilder append(Context someApplicationContext) {
this.bObject.object2 = somehowComputeObject2();
}
}
If you employ this fluent builder with fluent facade builder pattern, you can then use it like so:
BusinessObject complexBusinessObject = BusinessObject.create()
.debug("Let's build team1Object.")
.team1Object().append( /* someApplicationContext */)
.debug("Let's build team2Object.")
.team2Object().append( /* someApplicationContext */)
.debug("All done.")
.build();
But then I'm not sure if this is what you wanted to achieve, particularly because I'm not exquisitely familiar with Team1 and Team2 objects or how you might would define them in terms of duty and hierarchy.
You mentioned chain of responsibility. This pattern is used when a chain of components each get a turn (in a chain) to process a command/query, and optionally stop the chain from proceeding.
Consider a process such as hiring an employee. There are several processes along the way. As each process is completed, the next process in the chain begins. If an exception occurs, perhaps the employee isn't hired after all (stopping the chain).
For this we have a chain of responsibilities and we would use the chain of responsibility design pattern. If, for example, Team2 processes depend on Team1 processes, you can use this pattern as it would solve this issue.
In order to use a chain of responsibility pattern, you will need the BusinessObject as well as one or more BusinessObjectModifier classes. Since the scope here is limited to Team1Appender and Team2Appender objects, we'll use those two as a reference.
In order to build the chain, you might want a base class to use for a next field for the next link in the chain and an add() method to hand-off to the next responsible link in the chain.
Consider the following chain of responsibility pattern:
public class BusinessObject {
public Team1Object object1;
public Team2Object object2;
public String debug;
...
}
public abstract class BusinessObjectAppender { // provides shared append() modifier
protected BusinessObjectAppender next = null;
public void add(BusinessObjectAppender boa) {
if (this.next == null) {
this.next = boa;
}
else {
next.add(boa); // recursive call to the end of the linked list "chain"
}
}
public abstract void append(BusinessObject businessObject, Context someApplicationContext);
}
public class Team1ObjectAppender extends BusinessObjectAppender {
public BusinessObject append(BusinessObject businessObject, Context someApplicationContext) {
Team1Object object1 = somehowComputeObject1();
businessObject.object1 = object1;
if (this.next == null) {
return businessObject; // you have to since you can't pass by ref/out in java
}
else {
return next.append(businessObject, someApplicationContext);
}
}
}
public class Team2ObjectAppender extends BusinessObjectAppender {
public BusinessObject append(BusinessObject businessObject, Context someApplicationContext) {
Team2Object object2 = somehowComputeObject2();
businessObject.object2 = object2;
if (this.next == null) {
return businessObject; // you have to since you can't pass by ref/out in java
}
else {
return next.append(businessObject, someApplicationContext);
}
}
}
Now, this should set up the chain. To use it, you might do something like:
BusinessObject businessObject = new BusinessObject();
BusinessObjectAppender appendChain = new Team1ObjectAppender();
appendChain.add(new Team2ObjectAppender()); // start --> team1 --> team2 --> done
businessObject = appendChain(businessObject, /*someApplicationContext*/);
Does this solve your problem? If you have a chain of responsibility, then perhaps.
I see your original specification used a builder as the subject to pass around the chain instead of the final object. This is an interesting intersection of the two patterns.
If you wanted to use a builder but then build an object using a chain of responsibility method, you might consider something along the lines of:
public class BusinessObject {
internal BusinessObject() {
// Default constructor should exist
// but only needs to be visible at the
// BusinessObjectBuilder scope.
// use whatever access modifier you would
// prefer, however, based on needs,
// internal or public is appropriate.
// in C++, use `friend BusinessObjectBuilder`
}
public Team1Object object1;
public Team2Object object2;
public String debug;
...
public static BusinessObjectBuilder create() {
return new BusinessObjectBuilder();
}
}
public abstract class BusinessObjectAppender { // provides shared append() modifier
protected BusinessObjectAppender next = null;
public void add(BusinessObjectAppender boa) {
if (this.next == null) {
this.next = boa;
}
else {
next.add(boa); // recursive call to the end of the linked list "chain"
}
}
public abstract void append(BusinessObject businessObject, Context someApplicationContext);
}
public class Team1ObjectAppender extends BusinessObjectAppender {
public BusinessObject append(BusinessObject businessObject, Context someApplicationContext) {
Team1Object object1 = somehowComputeObject1();
businessObject.object1 = object1;
if (this.next == null) {
return businessObject; // you have to since you can't pass by ref/out in java
}
else {
return next.append(businessObject, someApplicationContext);
}
}
}
public class Team2ObjectAppender extends BusinessObjectAppender {
public BusinessObject append(BusinessObject businessObject, Context someApplicationContext) {
Team2Object object2 = somehowComputeObject2();
businessObject.object2 = object2;
if (this.next == null) {
return businessObject; // you have to since you can't pass by ref/out in java
}
else {
return next.append(businessObject, someApplicationContext);
}
}
}
public class BusinessObjectBuilder {
protected BusinessObject bObject; // the object we will build
internal BusinessObjectBuilder() {
// A default constructor, again minimally visible
// to BusinessObject; internal or public is good here.
// Needs to create a basic BusinessObject.
bObject = new BusinessObject();
}
public BusinessObjectBuilder debug(String debugString) {
// Sets BusinessObject.debug
this.bObject.debug += debugString + "\n";
// Then returns the BusinessObjectBuilder.
// Every method should return this except the facade methods
// and the build method.
return this;
}
public BusinessObjectBuilder append(Context someApplicationContext) {
// Create the chain
BusinessObjectAppender appendChain = new Team1ObjectAppender();
appendChain.add(new Team2ObjectAppender()); // start --> team1 --> team2 --> done
this.bObject = appendChain(this.bObject, someApplicationContext);
// Return the Builder.
return this;
}
public BusinessObject build() {
// Technically, it's already built at this point. Return it.
return this.bObject;
}
}
And then use it like so:
BusinessObject complexBusinessObject = BusinessObject.create()
.debug("Run through the chain of responsibilities.")
.append( /* someApplicationContext */)
.debug("All done.")
.build();
This isn't the only way to intersect these two concepts. There are several endpoints where the lines blur between patterns, though I don't really wish to enumerate them all.
I would like to, of course, answer your questions.
Is it the right pattern? That depends on what you need.
Chain of responsibility consists of a source of command (the append() caller block in this case) which processes the command (append) through each processing object within a singly linked-list of a serially-sequenced series of processing objects (BusinessObjectAppender objects).
If you have no chain, it's definitely the wrong pattern. If you don't require a single source of command (calling append() in one place), then it's not necessarily the right design or could be refactored until it is.
Builder pattern provides a solution for building a complex object when a constructor just doesn't cut it. In this case, constructing such an object is itself a separate concern, and therefore construction is broken off of the class it is building and put into a separate builder class.
If you need a way to construct an object which is different than the way it will be represented, it could be the right pattern.
For example, the way in which an automobile is presented to a driver or buyer or seller is most certainly not using the same interfaces that were used to build it in a factory. Of course, it will have a make, model, and year, all the same. But the customer isn't concerned with the cost of parts, time it takes to build, test results for various systems tests, which employees were involved on the days it was being built. But, sure enough, it goes 0-60 in 6.5 seconds and was painted the color red.
When building an object is complex and representation differs from the way in which it is built, a Builder pattern will solve it. (And it looks nice when you use a fluent approach.)
Both the builder pattern and the chain of responsibility pattern are part of the original "Gang of Four" design patterns.
Where they differ is Builder pattern is a Creational pattern and Chain of Responsibility is a Behavioral pattern.
I don't aim to rewrite the book, so I could just refer you to the title, "Design Patterns: Elements of Reusable Object-Oriented Software" (1994. Gamma, Erich; Helm, Richard; Johnson, Ralph; and Vlissides, John.) if you are looking to match one of their patterns to your own needs. Since you haven't explained the purpose of team 1 and team 2, I can't decide for you what is best.
What are the other ways?
The Gang of Four provided a few other Creational and Behavioral patterns.
If Chain of Responsibility doesn't solve your problem, then a Command pattern might. (That's pretty much what the BusinessObjectAppender.append() abstract method did for you, minus the chain; as append() is roughly execute() once implemented.)
If you need to execute the same Command for the same subject across several (1...n) processes, but where the processes are not linked together in a responsibility chain and require no particular order, then a simple Iterator would do fine. Fortunately Java provides many facilities which are iterable very easily. Consider ArrayList<Appender> appenders.
There are many, many options to choose from. Sometimes you can mix them up.
I actually picked up a design patterns class on Udemy, specifically for C++, but there's many places online where you can find this information. This looks like a good source of summaries, particularly because the examples are in Java, and offer alternatives to the design choices I chose, giving you some extra examples: JournalDev.
Hopefully, that helps point you in the right direction.

usage of visitor pattern

I have a class like this
public EmployeeRepositoryImpl{
public Employee save(final Employee employee) {
return employeeDao.save(sanitizeEmployee(employee));
}
Employee sanitizeEmployee(Employee employee){
employee.setName(cleanUpBadData(employee.getName());
employee.setPhone(cleanUpBadData(employee.getPhone());
employee.setAddress(cleanUpBadData(employee.getAddress());
......
return employee;
}
private static String cleanUpBadData(String attribute) {
//cleanbaddata here
return attribute;
}
}
I want to refactor this using visitor pattern incase tomorrow we need to add additional logic like cleanup Which I added today.I am not sure I did visitor pattern correctly since I do not have a accept method and Visitable.Can anyone please correct me the right way to do it.
I created
public interface EmployeeVisitor {
void visitEmployee(Employee employee);
}
public class EmployeeVisitorImpl implements EmployeeVisitor {
public void visitEmployee(Employee employee)
{
employee.setName(cleanUpBadData(employee.getName());
employee.setPhone(cleanUpBadData(employee.getPhone());
employee.setAddress(cleanUpBadData(employee.getAddress());
......
return employee;
}
private static String cleanUpBadData(String attribute) {
//cleanbaddata here
return attribute;
}
}
A correct implementation of the visitor pattern would look like this:
interface EmployeeVisitor {
void visitEmployee(Employee employee);
}
class CleanUpEmployee implements EmployeeVisitor {
void visitEmployee(Employee employee) {
...
}
}
class Employee {
void accept(EmployeeVisitor visitor) {
visitor.visitEmployee(this);
}
}
The visitor pattern is specifically designed to separate one or more algorithms from a class structure they operate on. There is no point to the visitor pattern unless there is a class structure you are trying to make your algorithms independent of. In your case you don't seem to have any extensions of Employee so there's really no value to using visitors - just make the algorithms methods of the class.
If your intention is to be able to add additional operations to the class without changing it then there are other patterns that are probably more useful. For example https://en.wikipedia.org/wiki/Strategy_pattern allows the behaviour to be selected at runtime and https://en.wikipedia.org/wiki/Command_pattern allows the behaviour to be encapsulated with its context.

Which contract is satisfied [duplicate]

If I have two interfaces , both quite different in their purposes , but with same method signature , how do I make a class implement both without being forced to write a single method that serves for the both the interfaces and writing some convoluted logic in the method implementation that checks for which type of object the call is being made and invoke proper code ?
In C# , this is overcome by what is called as explicit interface implementation. Is there any equivalent way in Java ?
No, there is no way to implement the same method in two different ways in one class in Java.
That can lead to many confusing situations, which is why Java has disallowed it.
interface ISomething {
void doSomething();
}
interface ISomething2 {
void doSomething();
}
class Impl implements ISomething, ISomething2 {
void doSomething() {} // There can only be one implementation of this method.
}
What you can do is compose a class out of two classes that each implement a different interface. Then that one class will have the behavior of both interfaces.
class CompositeClass {
ISomething class1;
ISomething2 class2;
void doSomething1(){class1.doSomething();}
void doSomething2(){class2.doSomething();}
}
There's no real way to solve this in Java. You could use inner classes as a workaround:
interface Alfa { void m(); }
interface Beta { void m(); }
class AlfaBeta implements Alfa {
private int value;
public void m() { ++value; } // Alfa.m()
public Beta asBeta() {
return new Beta(){
public void m() { --value; } // Beta.m()
};
}
}
Although it doesn't allow for casts from AlfaBeta to Beta, downcasts are generally evil, and if it can be expected that an Alfa instance often has a Beta aspect, too, and for some reason (usually optimization is the only valid reason) you want to be able to convert it to Beta, you could make a sub-interface of Alfa with Beta asBeta() in it.
If you are encountering this problem, it is most likely because you are using inheritance where you should be using delegation. If you need to provide two different, albeit similar, interfaces for the same underlying model of data, then you should use a view to cheaply provide access to the data using some other interface.
To give a concrete example for the latter case, suppose you want to implement both Collection and MyCollection (which does not inherit from Collection and has an incompatible interface). You could provide a Collection getCollectionView() and MyCollection getMyCollectionView() functions which provide a light-weight implementation of Collection and MyCollection, using the same underlying data.
For the former case... suppose you really want an array of integers and an array of strings. Instead of inheriting from both List<Integer> and List<String>, you should have one member of type List<Integer> and another member of type List<String>, and refer to those members, rather than try to inherit from both. Even if you only needed a list of integers, it is better to use composition/delegation over inheritance in this case.
The "classical" Java problem also affects my Android development...
The reason seems to be simple:
More frameworks/libraries you have to use, more easily things can be out of control...
In my case, I have a BootStrapperApp class inherited from android.app.Application,
whereas the same class should also implement a Platform interface of a MVVM framework in order to get integrated.
Method collision occurred on a getString() method, which is announced by both interfaces and should have differenet implementation in different contexts.
The workaround (ugly..IMO) is using an inner class to implement all Platform methods, just because of one minor method signature conflict...in some case, such borrowed method is even not used at all (but affected major design semantics).
I tend to agree C#-style explicit context/namespace indication is helpful.
The only solution that came in my mind is using referece objects to the one you want to implent muliple interfaceces.
eg: supposing you have 2 interfaces to implement
public interface Framework1Interface {
void method(Object o);
}
and
public interface Framework2Interface {
void method(Object o);
}
you can enclose them in to two Facador objects:
public class Facador1 implements Framework1Interface {
private final ObjectToUse reference;
public static Framework1Interface Create(ObjectToUse ref) {
return new Facador1(ref);
}
private Facador1(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework1Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork1(o);
}
}
and
public class Facador2 implements Framework2Interface {
private final ObjectToUse reference;
public static Framework2Interface Create(ObjectToUse ref) {
return new Facador2(ref);
}
private Facador2(ObjectToUse refObject) {
this.reference = refObject;
}
#Override
public boolean equals(Object obj) {
if (obj instanceof Framework2Interface) {
return this == obj;
} else if (obj instanceof ObjectToUse) {
return reference == obj;
}
return super.equals(obj);
}
#Override
public void method(Object o) {
reference.methodForFrameWork2(o);
}
}
In the end the class you wanted should something like
public class ObjectToUse {
private Framework1Interface facFramework1Interface;
private Framework2Interface facFramework2Interface;
public ObjectToUse() {
}
public Framework1Interface getAsFramework1Interface() {
if (facFramework1Interface == null) {
facFramework1Interface = Facador1.Create(this);
}
return facFramework1Interface;
}
public Framework2Interface getAsFramework2Interface() {
if (facFramework2Interface == null) {
facFramework2Interface = Facador2.Create(this);
}
return facFramework2Interface;
}
public void methodForFrameWork1(Object o) {
}
public void methodForFrameWork2(Object o) {
}
}
you can now use the getAs* methods to "expose" your class
You can use an Adapter pattern in order to make these work. Create two adapter for each interface and use that. It should solve the problem.
All well and good when you have total control over all of the code in question and can implement this upfront.
Now imagine you have an existing public class used in many places with a method
public class MyClass{
private String name;
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Now you need to pass it into the off the shelf WizzBangProcessor which requires classes to implement the WBPInterface... which also has a getName() method, but instead of your concrete implementation, this interface expects the method to return the name of a type of Wizz Bang Processing.
In C# it would be a trvial
public class MyClass : WBPInterface{
private String name;
String WBPInterface.getName(){
return "MyWizzBangProcessor";
}
MyClass(String name){
this.name = name;
}
public String getName(){
return name;
}
}
In Java Tough you are going to have to identify every point in the existing deployed code base where you need to convert from one interface to the other. Sure the WizzBangProcessor company should have used getWizzBangProcessName(), but they are developers too. In their context getName was fine. Actually, outside of Java, most other OO based languages support this. Java is rare in forcing all interfaces to be implemented with the same method NAME.
Most other languages have a compiler that is more than happy to take an instruction to say "this method in this class which matches the signature of this method in this implemented interface is it's implementation". After all the whole point of defining interfaces is to allow the definition to be abstracted from the implementation. (Don't even get me started on having default methods in Interfaces in Java, let alone default overriding.... because sure, every component designed for a road car should be able to get slammed into a flying car and just work - hey they are both cars... I'm sure the the default functionality of say your sat nav will not be affected with default pitch and roll inputs, because cars only yaw!

Is it okay to use the instanceof operator to implement two parallel hierarchies of functions and arguments to those?

Is it bad practice to use the instanceof operator in the following context?
public interface IWriter {
public abstract void write(Dto dto);
}
public abstract class Dto {
private long id;
public void setId(long id) {this.id = id;}
public long getId() {return id;}
}
public class DtoA extends Dto {
...
}
public class DtoB extends Dto {
...
}
public class MyWriterA implements IWriter {
#Override
public void writer(Dto dto) {
if (!(dto instanceof DtoA))
return;
...
}
}
public class MyWriterB implements IWriter {
#Override
public void writer(Dto dto) {
if (!(dto instanceof DtoB))
return;
...
}
}
There is a lot of myths about the use of that operator and I am not completely
sure that what I am doing is not bunk.
I have a lot of different writer implementations
which I want to combine in one interface. The problem is not every DTO is applicable for every writer. In my actual code there is a deep hierarchy of DTOs, which extend DtoA and DtoB, and either the
hierarchy branch of DtoA or DtoB is applicable for a writer, but only in a few cases both.
Should I avoid using the abstract class Dto as argument for the abstract write(Dto dto) method?
EDIT: Please read the comments on the accepted answer.
Sometimes there's no getting around using instanceof - there is no need to feel shame.
Typing IWriter may help:
public interface IWriter<T extends Dto> {
public abstract void write(T dto);
}
then
public class MyWriterA implements IWriter<DtoA> {
#Override
public void writer(DtoA dto) {
// No need for instanceof, because it can't be anything else
...
}
}
Perhaps a combination of such typing and Brian Agnew's worthy answer would do the trick.
How is the code calling the IWriter? Presumably you've got to determine the type up there too? In which case you already know what kind of writer you need. You're already dispatching on the basis of Type.
Your writers are not really substitutable WriterA only does As and so on. In which case you're not gaining anything by claiming they are in an inheritance hierarchy.
Have you looked at double-dispatch or the Visitor pattern ?
Essentially your Writer and DTO objects would mediate to call the correct methods e.g.
public void writer(Dto dto) {
dto.doSomething(writer);
}
and the doSomething() method called would depend on the type of the Dto. Your Dto object would implement a version for MyWriterA/B.
Using instanceOf isn't unavoidable, but is often a design smell, indicating that something isn't right, or could be done better.

Why would an Enum implement an Interface?

I just found out that Java allows enums to implement an interface. What would be a good use case for that?
Here's one example (a similar/better one is found in Effective Java 2nd Edition):
public interface Operator {
int apply (int a, int b);
}
public enum SimpleOperators implements Operator {
PLUS {
int apply(int a, int b) { return a + b; }
},
MINUS {
int apply(int a, int b) { return a - b; }
};
}
public enum ComplexOperators implements Operator {
// can't think of an example right now :-/
}
Now to get a list of both the Simple + Complex Operators:
List<Operator> operators = new ArrayList<Operator>();
operators.addAll(Arrays.asList(SimpleOperators.values()));
operators.addAll(Arrays.asList(ComplexOperators.values()));
So here you use an interface to simulate extensible enums (which wouldn't be possible without using an interface).
Enums don't just have to represent passive sets (e.g. colours). They can represent more complex objects with functionality, and so you're then likely to want to add further functionality to these - e.g. you may have interfaces such as Printable, Reportable etc. and components that support these.
The Comparable example given by several people here is wrong, since Enum already implements that. You can't even override it.
A better example is having an interface that defines, let's say, a data type. You can have an enum to implement the simple types, and have normal classes to implement complicated types:
interface DataType {
// methods here
}
enum SimpleDataType implements DataType {
INTEGER, STRING;
// implement methods
}
class IdentifierDataType implements DataType {
// implement interface and maybe add more specific methods
}
There is a case I often use. I have a IdUtil class with static methods to work with objects implementing a very simple Identifiable interface:
public interface Identifiable<K> {
K getId();
}
public abstract class IdUtil {
public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
for (T t : type.getEnumConstants()) {
if (Util.equals(t.getId(), id)) {
return t;
}
}
return null;
}
public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
List<T> list = new ArrayList<>();
for (T t : en.getDeclaringClass().getEnumConstants()) {
if (t.getId().compareTo(en.getId()) < 0) {
list.add(t);
}
}
return list;
}
}
If I create an Identifiable enum:
public enum MyEnum implements Identifiable<Integer> {
FIRST(1), SECOND(2);
private int id;
private MyEnum(int id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Then I can get it by its id this way:
MyEnum e = IdUtil.get(MyEnum.class, 1);
Since Enums can implement interfaces they can be used for strict enforcing of the singleton pattern. Trying to make a standard class a singleton allows...
for the possibility of using reflection techniques to expose private methods as public
for inheriting from your singleton and overriding your singleton's methods with something else
Enums as singletons help to prevent these security issues. This might have been one of the contributing reasons to let Enums act as classes and implement interfaces. Just a guess.
See https://stackoverflow.com/questions/427902/java-enum-singleton and Singleton class in java for more discussion.
It's required for extensibility -- if someone uses an API you've developed, the enums you define are static; they can't be added to or modified. However, if you let it implement an interface, the person using the API can develop their own enum using the same interface. You can then register this enum with an enum manager which conglomerates the enums together with the standard interface.
Edit: #Helper Method has the perfect example of this. Think about having other libraries defining new operators and then telling a manager class that 'hey, this enum exists -- register it'. Otherwise, you'd only be able to define Operators in your own code - there'd be no extensibility.
The post above that mentioned strategies didn't stress enough what a nice lightweight implementation of the strategy pattern using enums gets you:
public enum Strategy {
A {
#Override
void execute() {
System.out.print("Executing strategy A");
}
},
B {
#Override
void execute() {
System.out.print("Executing strategy B");
}
};
abstract void execute();
}
You can have all your strategies in one place without needing a separate compilation unit for each. You get a nice dynamic dispatch with just:
Strategy.valueOf("A").execute();
Makes java read almost like a tasty loosely typed language!
Enums are just classes in disguise, so for the most part, anything you can do with a class you can do with an enum.
I cannot think of a reason that an enum should not be able to implement an interface, at the same time I cannot think of a good reason for them to either.
I would say once you start adding thing like interfaces, or method to an enum you should really consider making it a class instead. Of course I am sure there are valid cases for doing non-traditional enum things, and since the limit would be an artificial one, I am in favour of letting people do what they want there.
Most common usage for this would be to merge the values of two enums into one group and treat them similarly. For example, see how to join Fruits and Vegatables.
For example if you have a Logger enum. Then you should have the logger methods such as debug, info, warning and error in the interface. It makes your code loosely coupled.
One of the best use case for me to use enum's with interface is Predicate filters. It's very elegant way to remedy lack of typness of apache collections (If other libraries mayn't be used).
import java.util.ArrayList;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
public class Test {
public final static String DEFAULT_COMPONENT = "Default";
enum FilterTest implements Predicate {
Active(false) {
#Override
boolean eval(Test test) {
return test.active;
}
},
DefaultComponent(true) {
#Override
boolean eval(Test test) {
return DEFAULT_COMPONENT.equals(test.component);
}
}
;
private boolean defaultValue;
private FilterTest(boolean defautValue) {
this.defaultValue = defautValue;
}
abstract boolean eval(Test test);
public boolean evaluate(Object o) {
if (o instanceof Test) {
return eval((Test)o);
}
return defaultValue;
}
}
private boolean active = true;
private String component = DEFAULT_COMPONENT;
public static void main(String[] args) {
Collection<Test> tests = new ArrayList<Test>();
tests.add(new Test());
CollectionUtils.filter(tests, FilterTest.Active);
}
}
When creating constants in a jar file, it is often helpful to let users extend enum values. We used enums for PropertyFile keys and got stuck because nobody could add any new ones! Below would have worked much better.
Given:
public interface Color {
String fetchName();
}
and:
public class MarkTest {
public static void main(String[] args) {
MarkTest.showColor(Colors.BLUE);
MarkTest.showColor(MyColors.BROWN);
}
private static void showColor(Color c) {
System.out.println(c.fetchName());
}
}
one could have one enum in the jar:
public enum Colors implements Color {
BLUE, RED, GREEN;
#Override
public String fetchName() {
return this.name();
}
}
and a user could extend it to add his own colors:
public enum MyColors implements Color {
BROWN, GREEN, YELLOW;
#Override
public String fetchName() {
return this.name();
}
}
Another posibility:
public enum ConditionsToBeSatisfied implements Predicate<Number> {
IS_NOT_NULL(Objects::nonNull, "Item is null"),
IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"),
IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative");
private final Predicate<Number> predicate;
private final String notSatisfiedLogMessage;
ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) {
this.predicate = predicate;
this.notSatisfiedLogMessage = notSatisfiedLogMessage;
}
#Override
public boolean test(final Number item) {
final boolean isNotValid = predicate.negate().test(item);
if (isNotValid) {
log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage);
}
return predicate.test(item);
}
}
and using:
Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);
Enums are like Java Classes, they can have Constructors, Methods, etc. The only thing that you can't do with them is new EnumName(). The instances are predefined in your enum declaration.
Here's my reason why ...
I have populated a JavaFX ComboBox with the values of an Enum. I have an interface, Identifiable (specifying one method: identify), that allows me to specify how any object identifies itself to my application for searching purposes. This interface enables me to scan lists of any type of objects (whichever field the object may use for identity) for an identity match.
I'd like to find a match for an identity value in my ComboBox list. In order to use this capability on my ComboBox containing the Enum values, I must be able to implement the Identifiable interface in my Enum (which, as it happens, is trivial to implement in the case of an Enum).
I used an inner enum in an interface describing a strategy to keep instance control (each strategy is a Singleton) from there.
public interface VectorizeStrategy {
/**
* Keep instance control from here.
*
* Concrete classes constructors should be package private.
*/
enum ConcreteStrategy implements VectorizeStrategy {
DEFAULT (new VectorizeImpl());
private final VectorizeStrategy INSTANCE;
ConcreteStrategy(VectorizeStrategy concreteStrategy) {
INSTANCE = concreteStrategy;
}
#Override
public VectorImageGridIntersections processImage(MarvinImage img) {
return INSTANCE.processImage(img);
}
}
/**
* Should perform edge Detection in order to have lines, that can be vectorized.
*
* #param img An Image suitable for edge detection.
*
* #return the VectorImageGridIntersections representing img's vectors
* intersections with the grids.
*/
VectorImageGridIntersections processImage(MarvinImage img);
}
The fact that the enum implements the strategy is convenient to allow the enum class to act as proxy for its enclosed Instance. which also implements the interface.
it's a sort of strategyEnumProxy :P the clent code looks like this:
VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
If it didn't implement the interface it'd had been:
VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);

Categories