How to implement pattern matching in java and avoid instanceof? - java

At the moment I don't know how to avoid code smells in my piece of code.
I've tried several patterns (Strategy, Visitor) and they didn't provide a clean and maintainable solution. Here is an example of my code for strategy pattern:
public interface Strategy {
<T> T foo(FirstParam firstParam, SecondParam secondParam);
}
public class StrategyOne implements Strategy {
FirstReturnType foo(FirstParam firstParam, SecondParam secondParam);
}
public class StrategyTwo implements Strategy {
SecondReturnType foo(FirstParam firstParam, SecondParam secondParam);
}
#Setter
public class Context {
private Strategy strategy;
public void execute(FirstParam firstParam, SecondParam secondParam) {
if (strategy != null) {
strategy.fo(firstParam, secondParam);
}
}
}
And there is a example of objects.
public abstract class Action {
abstract void bar();
}
public class ActionOne extends Action {
void bar() {}
}
public class ActionTwo extends Action {
void bar() {}
}
And I want to make this piece of code cleaner
public class ActionExecutor {
private Context context;
private FirstParam firstParam;
private SecondParam secondParam;
public ActionExecutor(FirstParam firstParam, SecondParam secondParam) {
this.context = new Context();
this.firstParam = firstParam;
this.secondParam = secondParam;
}
public void doSmth(Item item) {
Action action = item.getAction();
if(action instanceof ActionOne) {
context.setStrategy(new StrategyOne());
}
if(action instanceof ActionTwo) {
context.setStrategy(new StrategyTwo());
}
context.execute(firstParam, secondParam);
}
}
The idea is to perform a specific action for a specific object type. But I don't know how to avoid the usage of instanceof in this situation.

Two ways top of my head.
public abstract class Action {
public Strategy strategy;
abstract void bar();
}
public class ActionOne extends Action {
void bar() {}
// set strategy here, possibly
}
public class ActionTwo extends Action {
void bar() {}
}
public void doSmth(Item item) {
Action action = item.getAction();
action.strategy.execute(firstParam, secondParam);
}
Second way, have an enum in all your actions and force it by declaring it as a parameter in your abstract class constructor. Then just use switch in instead of instanceof

Could be something like this:
public void doSmth(Item item) {
Action action = item.getAction();
Map<String,Strategy> strategies = new HashMap<>();
strategies.put(ActionOne.getClass().getSimpleName(),new StrategyOne());
strategies.put(ActionTwo.getClass().getSimpleName(),new StrategyTwo());
..
strategies.put(ActionHundred.getClass().getSimpleName(),new StrategyHundred());
if(strategies.containsKey(action.getClass().getSimpleName())) {
context.setStrategy(strategies.get(action.getClass().getSimpleName()));
}
context.execute(firstParam, secondParam); }

This seems like a textbook use case for the Factory Method pattern. You can use the same code you have now (or the Map example in another answer), but put it in a factory - then it's purpose-specific and decoupled from the code that uses it.
Something like this.
public class StrategyFactory {
public static Stategy getStrategy(Action action) {
if(action instanceof ActionOne) {
return new StrategyOne();
} else if(action instanceof ActionTwo) {
return new StrategyTwo();
}
}
}
And then, something like this.
Action action = item.getAction();
action.setStrategy(StrategyFactory.getStrategy(action));
There's another example here: https://dzone.com/articles/design-patterns-the-strategy-and-factory-patterns

Related

Referencing boolean in interface

I ran into a bit of an issue and was hoping someone could tell me what I'm missing here.
for some context I have the following methods:
private boolean windowork;
public class WinidowMalfunction extends Event {
ControllerException newException = new ControllerException("Error:");
public WinidowMalfunction(long delayTime) {
super(delayTime);
}
public void action() throws ControllerException {
windowork = false;
someThingWentWrongHere(1, "Error at WinidowMalfunction");
}
}
private boolean poweron;
public class PowerOut extends Event {
public PowerOut(long delayTime) {
super(delayTime);
}
public void action() throws ControllerException {
poweron = false;
someThingWentWrongHere(2, "Error at powerOut event");
}
}
and I'm creating interface Fixable where I need to change the value of poweron and windowork to change their values to true. but I can't get the FIxable to accept the references. they are all in the same class so is there a way to reference these boolean function in an interface
EDIT:
Assignment question:
In this part, we add functionality for restoring the saved GreenhouseControls object and having it resume execution where it left off. It demonstrates the use of interfaces and the capability of Java methods to return objects.
Create the following interface
interface Fixable {
// turns Power on, fix window and zeros out error codes
void fix ();
// logs to a text file in the current directory called fix.log
// prints to the console, and identify time and nature of
// the fix
void log();
}
You can do something like this:
interface Fixable {
public boolean setTrue();
}
class Foo implements Fixable {
private boolean windowork = false;
public void setTrue() {
windowork = true;
}
}
class Bar implements Fixable {
private boolean poweron = false;
public void setTrue() {
poweron = true;
}
}
The only advantage of the above is if you had an array of Fixable objects you could iterate thru them and do this.
for (Fixable f : fixableArray) {
f.setTrue();
}
An interface can be designed in a way to read-write a boolean property that resides in the class/instance.
public interface Somename {
public boolean isPowerOn();
public void setPowerTo(boolean arg);
}

Interface segregation principle application

I'm wondering if the Interface segregation principle applys to my codebase.
Here's some example code:
First Class:
public class EntityGroup {
public List<Entity> tests;
//returns true if the EntityGroup is valid
public boolean validate() {
for (Entity test : tests) {
if (!test.validateFieldA() || !test.validateFieldB()) {
return false;
}
}
return true;
}
}
Second Class:
public abstract class Entity {
protected String fieldA;
public abstract boolean validateFieldA();
public abstract boolean validateFieldB();
}
Third Class:
public class EntityChild extends Entity {
private String fieldB;
#Override
public boolean validateFieldA() {
if (fieldA.equals("valid")) {
return true;
} else {
return false;
}
}
#Override
public boolean validateFieldB() {
if (fieldB.equals("valid")) {
return true;
} else {
return false;
}
}
}
Fourth Class:
public class EntityChild2 extends Entity {
#Override
public boolean validateFieldA() {
if (fieldA.equals("valid")) {
return true;
} else {
return false;
}
}
#Override
public boolean validateFieldB() {
return true;
}
}
This is a greatly simplified example from my real codebase but I think it illustrates the problem well. My EntityChild2 class is forced to implement a method it does not need or want to know about.
I know that it would be more correct to have a Interface that would contain the validateFieldB() method and only have EntityChild implement that interface.
With the understanding that this would take a significant amount of effort to refactor into this solution, I'm having a hard time justifying the time it would take to implement this solution in my real code base.
What potential problems will I run into down the line by leaving my code this way?
What benefits will I gain from refactoring my code to have a separate interface for validateFieldB()?
tldr: Why is the Interface Segregation Principle so important?
Wrong Abstraction
You make use of the interface segregation principle but with wrong abstractions.. Your different Entity-types differ only in they behavior.
Because of the shared behavior you have duplicate code in the methods validateFieldA of EntityChild and EntityChild2 . The method validateFieldB looks very similar to validateFieldA just the filed for checking the equality is an other.
You only need one Entity
Strategy Pattern
With the Strategy-Pattern you will have no duplicate code:
class EqualValidationStategy() implements ValidationStategy<T> {
#Override
public boolean check(T a, T b) {
return a.equals(b)
}
}
class TrueValidationStategy() implements ValidationStategy<T> {
#Override
public boolean check(T a, T b) {
return true;
}
}
Entity
public class Entity {
private String fieldA;
private String fieldB;
private ValidationStategy<String> validationForA;
private ValidationStategy<String> validationForB;
// all-args consturctor
#Override
public boolean validateFieldA() {
return validationForA.check(fieldA, "valid");
}
#Override
public boolean validateFieldB() {
return validationForB.check(fieldB, "valid");
}
}
// Validates fieldA and "ignores" fieldB
Entity example = new Entity(fieldA,
fieldB,
new EqualValidationStategy(),
new TrueValidationStategy());

Using a base enum as a default for dependent enums

I'm working on a client that uses a standardised web service, however one of the vendors behaves in a slightly different way such that we must take account of these behaviours. To do this we have been using an enum:
public enum ServiceProviderType {
FOO, BAR;
public ServiceProviderType checkService(String url) {
if (url.equals("http://www.example.com")) {
return ServiceProviderType.FOO;
} else {
return ServiceProviderType.BAR;
}
}
}
The difference in these behaviours also differ according to what we request from the service, eg we might request a layer and want that layer coloured red, but know that BAR and FOO services represent RGB values differently. To do this we've created another enum that stores the properties we want for each layer in the service.
public enum LayerServiceProviderType {
FOO("#ff0000"),
BAR("#ff5555");
private String colour;
public ServiceProviderType(String colour) {
this.colour = colour;
}
public String getColour() {
return colour;
}
public ServiceProviderType checkService(String url) {
if (url.equals("http://www.example.com")) {
return ServiceProviderType.FOO
} else {
return ServiceProviderType.BAR;
}
}
}
This works fine except for when we want to handle multiple layers and treat them as all being derivative of the same base enum. Essentially we want to handle Layer1ServiceProviderType.BAR as being equivalent to Layer2ServiceProviderType.BAR. But we can't subclass enums, and even attempting to do so seems to break all kinds of sound design principles.
My first thought was to have an interface which contains an enum:
interface ServiceProvider {
ServiceProviderType {FOO, BAR};
ServiceProviderType getServiceProviderType();
ServiceProvider checkService(String url);
}
public enum LayerServiceProvider implements ServiceProvider {
FOO (ServiceProviderType.FOO, "#ff0000"),
BAR (ServiceProviderType.BAR, "#ff0000");
public LayerServiceProvider(ServiceProviderType serviceProviderType, String colour) {
this.serviceProviderType = serviceProviderType;
this.colour = colour;
}
#Override
public ServiceProviderType getServiceProviderType() {
return this.serviceProviderType;
}
#Override
public ServiceProvider checkService(String url) {
if (url.equals("http://www.example.com")) {
return LayerServiceProviderType.FOO
} else {
return LayerServiceProviderType.BAR;
}
}
}
But it seems overwrought to me to have an enum with in an enum that each hold the same range of values. Is there a better way to do this?
Maybe the Visitor Pattern is what you're looking for.
Used with an enum, it basically allows adding enum-dependent logic without using switch statements.
Example:
public enum ServiceProviderType {
FOO {
#Override public <T> T apply(Action<T> action) { return action.doFoo(); }
},
BAR {
#Override public <T> T apply(Action<T> action) { return action.doBar(); }
};
public interface Action<T> {
T doFoo();
T doBar();
}
public abstract <T> T apply(Action<T> action);
public static ServiceProviderType checkService(String url) {
if (url.equals("http://www.example.com"))
return FOO;
return BAR;
}
}
public class LayerServiceProviderType implements ServiceProviderType.Action<String> {
#Override
public String doFoo() {
return "#ff0000";
}
#Override
public String doBar() {
return "#ff0000";
}
}
public class Main {
public static void main(String[] args) {
ServiceProviderType type = ServiceProviderType.checkService("");
String colour = type.apply(new LayerServiceProviderType());
}
}

Sad logic on types

Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}

dispatch design pattern?

Suppose I have a class hierarchy in Java:
interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
and I have another class in the same package:
class SpecialItemProcessor {
public void add(Item item)
{
/* X */
}
}
where I want to do something different for each item type, but I don't want to define that action in the different Item classes (MusicBox, TypeWriter, SoccerBall).
One way to handle this is:
class SpecialItemProcessor {
public void add(Item item)
{
if (item instanceof MusicBox)
{
MusicBox musicbox = (MusicBox)item;
... do something ...
}
else if (item instanceof MusicBox)
{
TypeWriter typewriter = (TypeWriter)item;
... do something ...
}
else if (item instanceof SoccerBall)
{
SoccerBall soccerball = (SoccerBall)item;
... do something ...
}
else
{
... do something by default ...
}
}
}
This works but it seems really clunky. Is there a better way to do this, when I know of special cases? (obviously if Item contains a method doSomethingSpecial then I can just call that item's method without caring what type it is, but if I don't want that differentiation to occur within the item itself how do I deal with it?)
In Java you can do multiple dispatch with a visitor(-like) pattern. The Item implementations don't need to contain the processing logic, they just need an accept() type of method.
public interface Item {
/** stuff **/
void processMe(ItemProcessor processor);
}
public interface ItemProcessor {
void process(MusicBox box);
void process(SoccerBall ball);
//etc
}
public class MusicBox implements Item {
#Override
public void processMe(ItemProcessor processor) {
processor.process(this);
}
}
public class ItemAddingProcessor implements ItemProcessor {
public void add(Item item) {
item.processMe(this);
}
#Override
public void process(MusicBox box) {
//code for handling MusicBoxes
//what would have been inside if (item instanceof MusicBox) {}
}
//etc
}
I think I'm going to use the idea of inversion of control and the visitor pattern:
interface Item {
public void accept(Visitor visitor);
...
public interface Visitor {
public void visit(Item item);
}
}
class MusicBox implements Item {
public interface Visitor extends Item.Visitor {
public void visitMusicBox(MusicBox item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof MusicBox.Visitor)
{
((MusicBox.Visitor)visitor).visitMusicBox(this);
}
}
}
class TypeWriter implements Item {
public interface Visitor extends Item.Visitor {
public void visitTypeWriter(TypeWriter item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof TypeWriter.Visitor)
{
((TypeWriter.Visitor)visitor).visitTypeWriter(this);
}
}
}
class SoccerBall implements Item {
public interface Visitor extends Item.Visitorr {
public void visitSoccerBall(SoccerBall item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof SoccerBall.Visitor)
{
((SoccerBall.Visitor)visitor).visitSoccerBall(this);
}
}
}
and then do the following, which at least reduces the instanceof to one check per add() call:
class SpecialItemProcessor
implements
MusicBox.Visitor,
TypeWriter.Visitor,
SoccerBall.Visitor,
Item.Visitor
{
public void add(Item item)
{
item.accept(this);
}
#Override public void visitMusicBox(MusicBox item)
{
...
}
#Override public void visitTypeWriter(TypeWriter item)
{
...
}
#Override public void visitSoccerBall(SoccerBall item)
{
...
}
#Override public void visit(Item item)
{
/* not sure what if anything I should do here */
}
}
Why not define some callback function to Item interface?
public Interface Item {
void onCallBack();
}
Then in each class that implements Item, such as MusicBox, it should implement the callback function.
public class MusicBox {
#override
public void onCallBack() {
// business logic
...
...
}
}
Then you could create a dispatcher, which you name is "SpecialItemProcessor".
public SpecialItemProcessor {
private final Item _item;
public SpecialItemProcessor(Item item) {
_item = item;
}
public dispatch() {
_item.onCallBack()
}
}
And then, in the Client class which contains the SpecialItemProcessor could just call the method, like:
public void XXXX() {
....
SpecialItemProcessor specialItemProcessor = new SpecialItemProcessor(new MusicBox());
specialItemProcessor.dispatch();
....
}
Actually, in C++, this is Dynamic Binding. And this is why pure abstract class exists...
You could create a bridge pattern for Item, in which the other side were the associated processes to do when add() is called. You could also add a factory method to the mix.
class SpecialItemProcessor {
public void add(Item item)
{
Process p = Item.createCorrespondingProcessor( p );
p.doWhenAddin();
}
}
Hope this helps.

Categories

Resources