creating objects and polymorphism - java

I want to avoid using tagged classes and big if-else blocks or switch statement and use polymorphism with a class hierarchy instead, which I believe is better practice.
For example, something like the below, where the choice of executed method is dependent only one one field of an object of type Actor.
switch(actor.getTagField())
{
case 1: actor.act1(); break;
case 2: actor.act2(); break;
[...]
}
would become
actor.act();
and the act method would be overridden in subclasses of Actor.
However, the most obvious way to decide at runtime which subclass to instantiate looks awfully similar to the original:
Actor newActor(int type)
{
switch(type)
{
case 1: return new Actor1();
case 2: return new Actor2();
[...]
}
}
so it seems like nothing has really been gained; the logic has just been moved.
What is a better way to do this? The only way I can come up with involved implementing a factory class for each subclass of Actor, but this seems rather cumbersome for such a simple problem.
Am I overthinking this? It just seems like there's no point making the original change if I just do pretty much the same thing elsewhere.

Question is "if" you need a factory. The factory is meant to manage the creation of instances an not so much the behavior of related instances.
Otherwise, you're just looking at basic inheritance. Something like..
class Actor{
public void act(){
System.out.println("I act..");
}
}
class StuntActor extends Actor {
public void act(){
System.out.println("I do fancy stunts..");
}
}
class VoiceActor extends Actor {
public void act(){
System.out.println("I make funny noises..");
}
}
To Use, you can just instantiate the type of actor you need directly.
Actor fred = new Actor();
Actor tom = new VoiceActor();
Actor sally = new StuntActor();
fred.act();
tom.act();
sally.act();
Output:
I act..
I make funny noises..
I do fancy stunts..
EDIT:
If you need to centralize the creation of the Actors..aka vis a Factory, you will not be able to get away from some kind of switching logic--in which case..i'll typically use an enumeration for readability:
public class Actor{
public enum Type{ REGULAR, VOICE, STUNT }
public static Actor Create(Actor.Type type){
switch(type) {
case VOICE:
return new VoiceActor();
case STUNT:
return new StuntActor();
case REGULAR:
default:
return new Actor();
}
}
public void act(){
System.out.println("I act..");
}
}
Usage:
Actor some_actor = Actor.Create(Actor.Type.VOICE);
some_actor.act();
Output:
I make funny noises..

Switch statements aren't pure evil. It's really duplication that you're looking to eliminate with better design. Often times you'll find the same switch statement show up in different (far away) places in your code - not necessarily doing the same thing, but switching on the same data. By introducing polymorphism, you pull those switches together as different methods of the same object.
This does two things, first it reduces several switches to one switch inside of a factory and it pulls together spread out logic that probably depends on similar data. That data will turn into member variables in your objects.
It's also worth noting that you don't always end up with a switch statement under the hood of your factory. Maybe you could scan the classpath at startup and build a HashMap of types that implement an interface. For example, consider an implementation of a socket protocol like SMTP. You could have objects named HeloCommand, MailFromCommand, etc... and find the right object to handle the message by matching the socket command to the class name.

I believe that you can do it with Abstract factory pattern...
This is a example:
abstract class Computer {
public abstract Parts getRAM();
public abstract Parts getProcessor();
public abstract Parts getMonitor();
}
class Parts {
public String specification;
public Parts(String specification) {
this.specification = specification;
}
public String getSpecification() {
return specification;
}
}
We have two class that extends Computer
class PC extends Computer {
public Parts getRAM() {
return new Parts("512 MB");
}
public Parts getProcessor() {
return new Parts("Celeron");
}
public Parts getMonitor() {
return new Parts("15 inches");
}
}
class Workstation extends Computer {
public Parts getRAM() {
return new Parts("1 GB");
}
public Parts getProcessor() {
return new Parts("Intel P 3");
}
public Parts getMonitor() {
return new Parts("19 inches");
}
}
And finally we have,
public class ComputerType {
private Computer comp;
public static void main(String[] args) {
ComputerType type = new ComputerType();
Computer computer = type.getComputer("Workstation");
System.out.println("Monitor: "+computer.getMonitor().getSpecification());
System.out.println("RAM: "+computer.getRAM().getSpecification());
System.out.println("Processor: "+computer.getProcessor().getSpecification());
}
public Computer getComputer(String computerType) {
if (computerType.equals("PC"))
comp = new PC();
else if(computerType.equals("Workstation"))
comp = new Workstation();
return comp;
}
}

Related

avoiding if conditions for similar type of checks

Is there anyway to avoid these if conditions? because there may be different type of objects coming in.
if ("OpenOrder".equals(order.getClass().getSimpleName())) {
return OpenOrderBuilder.createOFSMessage((OpenOrder) order); //Returns String
}
if ("ExecutionOrder".equals(order.getClass().getSimpleName())) {
return ExecutionOrderBuilder.createOFSMessage((ExecutionOrder) order); //Returns String
}
You can use a Router pattern to do this. Simple add the computations in a Map like this:
Map<String, Function> router = new HashMap<>();
router.put("OpenOrder", (value) -> OpenOrderBuilder.createOFSMessage((OpenOrder) value));
router.put("ExecutionOrder", (value) -> ExecutionOrderBuilder.createOFSMessage((ExecutionOrder) order));
And you can route the order using the String key. Here is a "OpenOrder" example:
String result = (String) router.get("OpenOrder").apply(order);
There are many ways to do it. Which one to choose, depends on your needs and in this case in particular on how many different types of objects you will have.
I suggest looking at concepts like interfaces and inheritance and on specific design patterns.
One approach I tend to like, although still not perfect, works as follows:
interface Order {
}
interface OrderBuilder<T> {
T forType();
Object createOFSMessage(Order order);
}
class OpenOrderBuilder<OpenOrder> implements OrderBuilder {
#Override
OpenOrder forType() {
return OpenOrder.class;
}
...
}
class ExecutionOrderBuilder<ExecutionOrder> implements OrderBuilder {
#Override
ExecutionOrder forType() {
return ExecutionOrder.class;
}
...
}
class MyProcessor {
Map<Class, OrderBuilder> obs;
public void initialize() {
List<OrderBuilder> builders = new ArrayList<>();
builders.add(new OpenOrderBuilder());
builders.add(new ExecutionOrderBuilder());
obs = new HashMap<Class, OrderBuilder>();
for(OrderBuilder b : builders) {
obs.put(b.forType(), b);
}
}
public Object createOFSMessage(Order order) {
return obs.get(order.getClass()).createOFSMessage(order);
}
}
In the above example, adding a new implementation would just consist of adding an entry to the builders collection. While in the example above it's done manually, normally this is done through Dependency Injection and frameworks like spring (in which case, the initialize method may turn into a constructor with builders as an #Autowired argument).
There are of course other ways, some more simple some more complicated. The best way really depends on what you have to do and one key rule: the less code you have the better.
First one should not forget the switch-on-string:
switch (order.getClass().getSimpleName()) {
case "OpenOrder":
return OpenOrderBuilder.createOFSMessage((OpenOrder) order); //Returns String
case "ExecutionOrder":
return ExecutionOrderBuilder.createOFSMessage((ExecutionOrder) order); //Returns String
}
The code however shows inheritance being used in combination with static child class factories. Evidently a createOFSMessage is not desired in the Order base class.
Then use a non-static "builder" - a factory. Follow the strategy pattern.
If you already know the type when calling the method, this code can help you :
private String CreateOFSMessage(Class<T> classOrder) {
if ("OpenOrder".equals(classOrder.getSimpleName())) {
return OpenOrderBuilder.createOFSMessage((classOrder) order);
}else if ("ExecutionOrder".equals(classOrder.getSimpleName())) {
return ExecutionOrderBuilder.createOFSMessage((classOrder) order);
}
}

How eliminate switch in this specific example

I have controller method that get data from request and based on subject variable from request decide to call a function. (for project need I cannot use seperate controller method for each subject variable)
For now I used switch but I think it breaks Open Closed Principle (because every time new type of subject added I have to add new case to switch) and not good design, How can I refactor this code?
Subject subject = ... //(type of enum)
JSONObject data = request.getData("data");
switch(subject) {
case SEND_VERIFY:
send_foo1(data.getString("foo1_1"), data.getString("foo1_2"));
break;
case do_foo2:
foo2(data.getInt("foo2_b"), data.getInt("foo2_cc"));
break;
case do_foo3:
do_foo3_for(data.getString("foo3"));
break;
// some more cases
}
While I am not sure about which OO principle this snippet violates, there is indeed a more roust way to achieve the logic: tie the processing for each enum value to the enum class.
You will need to generalize the processing into an interface:
public interface SubjectProcessor
{
void process(JSONObject data);
}
and create concrete implementations for each enum value:
public class SendVerifySubjectProcessor implements SubjectProcessor
{
#Override
public void process(JSONObject data) {
String foo1 = data.getString("foo1_1");
String foo2 = data.getString("foo1_2");
...
}
}
once you have that class hierarchy tree, you can associate each enum value to a concrete processor
public enum Subject
{
SEND_VERIFY(new SendVerifySubjectProcessor()),
do_foo2(new Foo2SubjectProcessor()),
...
private SubjectProcessor processor
Subject(SubjectProcessor processor) {
this.processor = processor;
}
public void process(JSONObject data) {
this.processor.process(data);
}
}
This eliminates the need for the switch statement in the controller:
Subject subject = ... //(type of enum)
JSONObject data = request.getData("data");
subject.process(data);
EDIT:
Following the good comment, You can utilize the java.util.function.Consumer functional interface instead of the custom SubjectProcessor one. You can decide whether to write concrete classes or use the lambda expr construct.
public class SendVerifySubjectProcessor implements Consumer<JSONObject>
{
#Override
public void accept(JSONObject data) {
String foo1 = data.getString("foo1_1");
String foo2 = data.getString("foo1_2");
...
}
}
OR
public enum Subject
{
SEND_VERIFY(data -> {
String foo1 = data.getString("foo1_1");
String foo2 = data.getString("foo1_2");
...
}),
...
private Consumer<Subject> processor
Subject(Consumer<Subject> processor) {
this.processor = processor;
}
public void process(JSONObject data) {
this.processor.accept(data);
}
}
// SubjectsMapping.java
Map<Subject, Consumer<JSONObject>> tasks = new HashMap<>();
tasks.put(SEND_VERIFY,
data -> send_foo1(data.getString("foo1_1"), data.getString("foo1_2")));
tasks.put(do_foo2,
data -> foo2(data.getInt("foo2_b"), data.getInt("foo2_cc")));
tasks.put(do_foo3, data -> do_foo3_for(data.getString("foo3")));
// In your controller class where currently `switch` code written
if (tasks.containsKey(subject)) {
tasks.get(subject).accept(data);
} else {
throw new IllegalArgumentException("No suitable task");
}
You can maintain Map<Subject, Consumer<JSONObject>> tasks configuration in separate class rather than mixing with if (tasks.containsKey(subject)) code. When you need another feature you can configure one entry in this map.
Answers of others seems to be great, as an addition I would suggest using EnumMap for storing enums as keys as it might be more efficient than the standard Map. I think it's also worth mentioning that the Strategy Pattern is used here to achieve calling specific actions for each key from Map without the need of building long switch statements.

What design pattern is this? Adapter?

[See below for updates]
I am having a hard time defining a pattern. My colleague says it's adaptor pattern. I'm not sure. We're stuck mainly because we want to correctly name our components.
Question: Is it adapter pattern? If not what is it? If it is something else, is this the best way to implement the idea?
To put it in summary, it is a main component(is this the adapter?) that shares an interfaces with sub-components (are these providers?). The main components decides/orchestrates which of the sub-components are called. The main component behaves as some sort of "wrapper" to call one of the others that have the same interface. The instances of which are injected through the constructor.
Assumptions:
For simplicity, we will ignore DR/IoC for now, but we understand and apply the pattern/principle.
The code is not the best implemented form...feel free to suggest.
My use of the words main/sub does not infer some kind of inheritence...just bad naming on my part, if confusing.
It's language-agnostic, because I love contributions from C# and Java guys, and the knowledge they share.
I am using a Social Networking scenario where a main component gets stats on a hastag and instantiates the appropriate Social Sub Component (
There is a Social Component interface:
ISocialComponent
{
SomeStatsObject GetStats(string hashTag);
}
Social Sub-Components implement ISocialComponent Interface
Twitter Sub-Component
public class TwitterSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hashTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Twitter-specific code goes here
}
}
Facebook Sub-Component
public class FacebookSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hashTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Facebook-specific code goes here
}
}
Instagram Sub-Component
public class InstagramSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hasTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Instagram-specific code goes here
}
}
Main Component
There is a main social component object that calls any one of the Sub-Components (defined below) that implement the shared ISocialComponent interface
public class MainSocialComponent : ISocialComponent
{
//this is an enum
private RequestedNetwork _requestedNetwork{ get; set;}
//the SocialComponent instance is injected outside of this class
private readonly ISocialComponent _socialComponent;
public MainSocialComponent(ISocialComponent socialComponent)
{
_socialComponent = socialComponent;
}
public SomeStatsObject GetStats(string hashTag)
{
return _socialComponent.GetStats(hashTag)
/**** original code, kept for historical purposes****
switch(_requestedNetwork)
{
case RequestedNetwork.Twitter:
var twit = new TwitterSubComponent();
return twit.GetStats(hashTag)
break;
case RequestedNetwork.Facebook:
var fb = new FacebookSubComponent();
return fb.GetStats(hashTag)
break;
case RequestedNetwork.Instagram:
var in = new InstagramSubComponent();
return in.GetStats(hashTag)
break;
default:
throw new Exception("Undefined Social Network");
break;
}*/
}
}
Updates:
I see why some say it is Factory pattern because it is creating objects. I had mentioned that we use an IoC container and DR. It was my mistake to exclude that. I have refactored the code
As others have mentioned, this is part of the Factory/Service pattern which is pretty popular for Dependency Injection and Inversion of Control.
Right now though there is no reason to declare your sub components as non static, since you aren't saving your instances to anything.
So it seems to me unless you have missing code where you add the components to a list or something, you could just do this:
public static class InstagramSubComponent : ISocialComponent
{
public static SomeStatsObject GetStats(string hashTag)
{
return stuff;
}
}
public class MainSocialComponent : ISocialComponent
{
//this is an enum
private RequestedNetwork _requestedNetwork{ get; set;}
private static var Mappings = new Dictionary<string, Func<SomeStatsObject>> {
{ "Twitter", TwitterSubComponent.GetStats },
{ "Facebook", FacebookSubComponent.GetStats },
{ "Instagram", InstagramSubComponent.GetStats }
}
public SomeStatsObject GetStats(string hashTag)
{
return Mappings[hashTag].invoke();
}
}
}
Now if you are doing stuff like actually saving your instances of sub components to a list for later or whatever, then that changes everything. But I am not seeing that so there's no reason not to just make it all static if these methods are simple.
If they are very complex then you'll want to use dependency injection so you can unit test everything proper.
I believe you can extract creation of SubComponent into a Factory and pass this Factory to MainSocialComponent. Inside of the GetStats method, you will call _factory.Create(hashTag); and than call GetStats on the returned object.
This way you'll have factory pattern.
This is definitely not an adapter pattern.
An adapter pattern does the following in most cases :
• Works as a bridge between two incompatible interfaces.
• Allows classes with incompatible interfaces work together
Your case is more like a Factory pattern. You use high level abstraction and return the type of interface/component whenever you need to.

What is a good java design pattern for similar objects with branching logic

I want to refactor an existing class of almost 5000 lines but I'm having difficulty with the constructor. Right now it's something like the following(methods here are in reality 10-30 blocks of code )
public MyClass( MyObject o ) {
if ( o.name.equalsIgnoreCase("a") ) {
doSomething()
} else {
doSomethingElse()
}
commonCode()
if (o.name.equalsIgnoreCase("a") ) {
doSecondThing()
} else {
doOtherSecondThing() //almost identical to doSecondThing but with some extra steps that absolutely have to be done in this sequence
}
// more of the same
}
I considered using inheritance and breaking things up into functions that would be overridden where necessary but that feels messy to me. Is there a pattern that fits this use case? Incidentally any advice on refactoring legacy code would be more than welcome.
You are exactly right. Refactoring like you described is called
Replace Conditional with Polymorphism.
Also you can look through on Chain-of-responsibility, Command or Strategy design patterns.
If every object follows the following pattern:
if(conditionA)
DoA();
else
DoElse();
Common();
if(conditionA2)
DoA2();
else if(conditionB2)
DoB2();
else
DoElse2();
Common2();
I'd advice you to have a common class that gathers handlers with conditions. This is roughly what I mean (Pseudo-code not java):
public interface IConditionalHandler
{
bool Condition();
void Action();
}
public class ActionHandler
{
private List<IConditionalHandler> m_FirstHandlers;
private List<IConditionalHandler> m_SecondHandlers; //Or possibly use a list of lists
public ActionHandler()
{
m_FirstHandlers = new ArrayList<>();
m_FirstHandlers.add(new HandlerA1());
m_FirstHandlers.add(new HandlerB1());
m_SecondHandlers = new ArrayList<>();
m_SecondHandlers.add(new HandlerA1());
m_SecondHandlers.add(new HandlerB1());
}
void DoStuff()
{
for(IConditionHandler handler : m_FirstHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
CommonA();
for(IConditionHandler handler : m_SecondHandlers)
{
if(handler.Condition())
{
handler.Action();
break;
}
}
}
}
If you have lots of segment, a list of lists can include your common code as an exit-handler and contain all of the logic. You delegate the logic out to implementing classes, and shorten the actual code in your class.
However, as far as efficiency goes you are going to kill both the instruction and data cache. If this isn't what you're looking for, then more than likely this is: Chain-of-Responsibility Pattern - Wikipedia

fuzzy implementation for capturing specific strings

I am going to develop a web crawler using java to capture hotel room prices from hotel websites.
In this case I want to capture room price with the room type and the meal type, so my algorithm should be intelligent to handle that.
For example:
Room type: Deluxe
Meal type: HalfBoad
price : $20.00
The main problem is room prices can be in different ways in different hotel sites. So my algorithm should be independent from hotel sites.
I am plan to use above room types and meal types as a fuzzy sets and compare the words in webpage with above fuzzy sets using a suitable membership function.
Anyone experienced with this? or have an idea for my problem?
There are two ways to approach this problem:
You can customize your crawler to understand the formats used by different Websites; or
You can come up with a general ("fuzzy") solution.
(1) will, by far, be the easiest. Ideally you want to create some tools that make this easier so you can create a filter for any new site in minimal time. IMHO your time will be best spent with this approach.
(2) has lots of problems. Firstly it will be unreliable. You will come across formats you don't understand or (worse) get wrong. Second, it will require a substantial amount of development to get something working. This is the sort of thing you use when you're dealing with thousands or millions of sites.
With hundreds of sites you will get better and more predictable results with (1).
As with all problems, design can let you deliver value adapt to situations you haven't considered much more quickly than the general solution.
Start by writing something that parses the data from one provider - the one with the simplest format to handle. Find a way to adapt that handler into your crawler. Be sure to encapsulate construction - you should always do this anyway...
public class RoomTypeExtractor
{
private RoomTypeExtractor() { }
public static RoomTypeExtractor GetInstance()
{
return new RoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
The GetInstance() ,ethod lets you promote to a Strategy pattern for practically free.
Then add your second provider type. Say, for instance, that you have a slightly more complex data format which is a little more prevalent than the first format. Start by refactoring what was your concrete room type extractor class into an abstraction with a single variation behind it and have the GetInstance() method return an instance of the concrete type:
public abstract class RoomTypeExtractor
{
public static RoomTypeExtractor GetInstance()
{
return SimpleRoomTypeExtractor.GetInstance();
}
public abstract string GetRoomType(string content);
}
public final class SimpleRoomTypeExtractor extends RoomTypeExtractor
{
private SimpleRoomTypeExtractor() { }
public static SimpleRoomTypeExtractor GetInstance()
{
return new SimpleRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// BEHAVIOR #1
}
}
Create another variation that implements the Null Object pattern...
public class NullRoomTypeExtractor extends RoomTypeExtractor
{
private NullRoomTypeExtractor() { }
public static NullRoomTypeExtractor GetInstance()
{
return new NullRoomTypeExtractor();
}
public string GetRoomType(string content)
{
// whatever "no content" behavior you want... I chose returning null
return null;
}
}
Add a base class that will make it easier to work with the Chain of Responsibility pattern that is in this problem:
public abstract class ChainLinkRoomTypeExtractor extends RoomTypeExtractor
{
private final RoomTypeExtractor next_;
protected ChainLinkRoomTypeExtractor(RoomTypeExtractor next)
{
next_ = next;
}
public final string GetRoomType(string content)
{
if (CanHandleContent(content))
{
return GetRoomTypeFromUnderstoodFormat(content);
}
else
{
return next_.GetRoomType(content);
}
}
protected abstract bool CanHandleContent(string content);
protected abstract string GetRoomTypeFromUnderstoodFormat(string content);
}
Now, refactor the original implementation to have a base class that joins it into a Chain of Responsibility...
public final class SimpleRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private SimpleRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static SimpleRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new SimpleRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// return whether or not content contains the right format
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #1
}
}
Be sure to update RoomTypeExtractor.GetInstance():
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
Once that's done, create a new link for the Chain of Responsibility...
public final class MoreComplexRoomTypeExtractor extends ChainLinkRoomTypeExtractor
{
private MoreComplexRoomTypeExtractor(RoomTypeExtractor next)
{
super(next);
}
public static MoreComplexRoomTypeExtractor GetInstance(RoomTypeExtractor next)
{
return new MoreComplexRoomTypeExtractor(next);
}
protected string CanHandleContent(string content)
{
// Check for presence of format #2
}
protected string GetRoomTypeFromUnderstoodFormat(string content)
{
// BEHAVIOR #2
}
}
Finally, add the new link to the chain, if this is a more common format, you might want to give it higher priority by putting it higher in the chain (the real forces that govern the order of the chain will become apparent when you do this):
public static RoomTypeExtractor GetInstance()
{
RoomTypeExtractor extractor = NullRoomTypeExtractor.GetInstance();
extractor = SimpleRoomTypeExtractor.GetInstance(extractor);
extractor = MoreComplexRoomTypeExtractor.GetInstance(extractor);
return extractor;
}
As time passes, you may want to add ways to dynamically add new links to the Chain of Responsibility, as pointed out by Cletus, but the fundamental principle here is Emergent Design. Start with high quality. Keep quality high. Drive with tests. Do those three things and you will be able to use the fuzzy logic engine between your ears to overcome almost any problem...
EDIT
Translated to Java. Hope I did that right; I'm a little rusty.

Categories