I have a file parser that reads text file line by line and creates a 'Event' object that represent the line.
There are 3 types of 'Event' so I created 4 pojos.
EventTypeA, EventTypeB, EventTypeC, EventTypeD that extend a BaseEvent that I push to an arraylist.
Pojos have nothing in common, as each pojo (event) has different set of fields.
Now I have an event handler that should handle all the events in the list based on the type.
I want the best elegant way to process them. I identified four options:
The obvious approach is via polymorphism, but those are pojos and I
don't want to put any business code there.
The second option is simply to check instanceof and casting
BaseEvent to concrete EventType to, but it's not elegant.
Third option is to add type field (enum) to pojo and then do a
'switch' checks (+ the casting) , but it's also not elegant.
Fourth option would be to create a hashmap, where key would be the
name of the pojo class, and the value will a instance of class with
code that handles it. I don't like that as well.
What can you suggest?
Thanks
There many possible solutions to this problem. However, the constraints you gave discard many of them. I think that the main issue here is trying to avoid to modify existing code each time a new Event type will be developed.
One possible solution is to use a Chain of responsibility on handlers. Define a common interface for handlers:
interface EventHandler {
void handle(BasicEvent event);
}
You will have a concrete handler implementation for each type of Event. Then, collect all the events in a common processor.
class EventProcessor {
private List<EventHandler> handlers;
public EventProcessor(List<EventHandler> handlers) {
this.handlers = handlers;
}
public void process(BasicEvent event) {
handlers.forEach(handler -> handler.handle(event));
}
}
In this way, every event will be processed only by the proper handler. Others handler will discard the event. Each time a new event will be develop, it will be sufficient to develop the relative handler and to add it to the chain.
There are many variant of this pattern. IMHO, this is the simplier one.
EDIT
For sake of completeness, if you can remove the requirement you stated at point
Fourth option would be to create a hashmap, where key would be the name of the pojo class, and the value will a instance of class with code that handles it
me and others (see comments below) think that the best approach should be really to have a dedicated Map for handlers.
class EventProcessor {
private Map<EventType, EventHandler> handlers;
public void process(BasicEvent event) {
handlers
.get(event.getType)
.handle(event);
}
}
The most important fact is that the above map handlers has to be built automatically, perhaps using dependency injection. Doing so, when you will add a new type of event, you can guarantee to not violate the Open Closed Principle of SOLID.
Cheers.
The pattern you want is the "Visitor":
https://sourcemaking.com/design_patterns/visitor
I'm using it in a parser that I'm writing. I have an abstract class "AbstractNode", and a concrete class for each node type in the abstract syntax tree (BinaryOperationNode, AssignStatementNode, etc.). My parser gets a reference to the root node of the tree and then process each node sequentially. The Visitor pattern helps me to avoid writing a massive chain of if instanceof/else if(...).
The drawback is having to update the Visitor interface and each class that implements it each time that a new node type is created.
As it seems you main concern is decoupling the EventTypes from their handler I would recomend a Chain of responsibility.
It manages decoupling by passing the EventType among a chain of potential handlers.
Benfits
Reduced coupling, both handler and event have no explicit knowledge of each other
Ability to have multiple handlers per EventType to separate concerns
Concerns
It is not guaranteed that there will be a handler for the event type. This may be able to be addressed with a NotFound handler.
Related
We have 3 types of attributes in our project: CategoryAttribute, ProductAttribute and ProductTypeAttribute. These are outside of our control as they come from autogenerated classes and may contain attribute values of different types e.g. text, number or image. Now, each attribute has its own strategy to retrieve attributeValue. For simplicity, let's assume that all 3 of them have TextStrategy, NumberStrategy and ImageStrategy.
Example strategy:
#Component
public class CategoryImageAttributeStrategy implements CategoryAttributeStrategy {
#Override
public boolean isApplicable(CategoryAttribute attribute) {
return attribute.getImage() != null;
}
#Override
public Object getAttributeValue(CategoryAttribute attribute) {
//return attribute value here
//may be different or may be the same
//for ProductImageAttributeStrategy and ProductTypeImageAttributeStrategy
}
}
While getting image value may be different for all of them, getting text value is the same and we end up with 3 classes of almost the same code and I really really really don't like duplicating code.
I thought about creating an abstract class/default interface for each strategy type e.g. DefaultTextStrategy that all 3 text strategies would inherit from and either use default code provided higher or override it with own implementation, however I'm not really satisfied with this approach as it requires to create even more classes for such a simple task.
Maybe is it even possible to combine strategies of the same type (e.g. image) into one?
I would really like to hear what more experienced folks have to say in this matter as I would like to learn and improve.
Thanks in advance for your time.
There should be only 3 strategies. TextStrategy, NumberStrategy and ImageStrategy which extend the base strategy. Mixing attributes and strategy will make it confusing as both are actually independent and have many to many relationship with one another.
Let the 3 attributes extend a single Attribute class : CategoryAttribute, ProductAttribute and ProductTypeAttribute.
Let the strategies decide on what needs to be done based on the Attribute class object being passed to it. For Text strategy there would be single implementation. For Image strategy, you may require special handling for the one class.
Here's what I did:
First, I created an interface for all types of strategies named "AttributeValueStrategy". Then added 3 callbacks (type specific, e.g. NumberValueCallback etc.). Now, each strategy implements callback interface of its type and AttributeValueStrategy interface. Then there's DefaultStrategyMethods class that contains default "getAtrribute" for each type and the actual strategy call the defaultStrategyMethods (like below) or just implements its own code.
#Override
public Object getAttributeValue(Object attribute) {
return defaultStrategyMethods.getNumberValue(attribute, this);
}
Callbacks are created because only the actual strategy knows which class should it cast to (and has a method to do that), and DefaultStrategyMethods needs to use it so that's why I pass "this" as second argument (which is the callback itself).
No more duplicates, everything is clear and clean.
I understand the concept of Chain of Responsibility Pattern but maybe I'm wrongly using it.
I have several types of product and I have a controller that controls the interface that is displayed for each of these types of product. The user selects the type of product and each controller is responsible for showing and interacting with the appropriate interface.
For this, I'm using the chain of responsibility pattern which doesn't sound okay I think. What I'm doing is creating a chain of controllers and, as soon as I get the product type request, I just pass it to the chain of controllers and let the appropriate controller implement the request.
But when thinking, the same could have been achieved using a simple factory but with many conditional statements.
What do you think about the use of chain of responsibility in this situation?
As for me this task is defenitely not for chain of responsibility.
Usually in chain of responsibility the order of chain elements matters and here it is not the case.
I would try to do the following.
Create some kind of registry, which contains a map with key for productType and value for controller.
Sample implementation:
class ControllerRegistry
{
//declaration for map and constructor
public void Register(string productType, IProductController controller)
{
_map.Add(productType, controller);
}
public IProductController Find(string productType)
{
return _map[productType];
}
}
And during application startup you should register all you controllers by calling ControllerRegistry.Register method.
You get appropriate controller by calling ControllerRegistry.Find method.
As compared with chain of responsibility you will avoid the performanse hit if number of product types is large.
EDIT
Same task topic Design pattern for handling multiple message types
I'm working on designing a validator for certain objects (fields of those objects). These objects are enclosed in one, bigger object - container.
Example: Car as a container . Consists of Wheels, Engine, Body.
Lets say i need to validate if wheels have correct diameter, engine has correct capacity, body has certain length etc.
Theoretically I think I should validate everything before construction of a container (car).
What is the best way to achieve this? Do I make an abstract validator class with validate() method and implement it in every enclosed class? What about the container, do I just not include it at all in the validation process? Thanks for help.
I'd suggest you not to put the validation logic inside the classes you're going to validate.
I find it better to keep those classes as mere value objects, and create a parallel hierarchy of validators, roughly one for each entity to be validated. Alternatively, you could also create a single validator that can validate all the entities: however, this solution is less scalable and could bring you to violate the open-closed principle when you have to add a new entity (e.g. you want to deal also with the rear-view mirrors of the car).
Assuming you choose the one entity : one validator approach, the validator of the container will first validate the components inside the container and then validate if they fit together.
Please consider also the possibility of using validator frameworks such as Apache Commons Validator, that can save you from writing boilerplate code. However, since I don't know what kind of complex validation you have to perform, I don't know if it fits your needs.
Furthermore, I don't think you should be worried of validating everything before it is constructed. Just construct it and validate afterwards: then, if it violates the validation rules, you can discard it (i.e. don't persist it anywhere).
piggy backing off of gd1 answer, I agree. One such way would be to have a ValidatorAdapter for each of your value objects. So it would look like this:
public class GreenCarValidator {
public GreenCarValidator(Car car) {
// save reference
}
#Override
public boolean isValid() {
return car.getColor().equals("green");
}
}
public class RedCarValidator {
public RedCarValidator(Car car) {
// save reference
}
#Override
public boolean isValid() {
// you could compose more validators here for each property in the car object as needed
return car.getColor().equals("red");
}
}
Now you can have many types of validators for a single type of object, dynamic and configurable at runtime. Should you put the "valid()" method inside the classes the classes as gd1 suggest you not do, you would lose this flexibility.
You could create a ValidatablePart interface with a validate method, have all parts implement this interface, and then have the container validate all inclosed parts as they are being added to the container or perhaps when calling the the container's build or whatever method that is supposed to construct it.
Your Container class could follow the Template Method Design Pattern.
I'm wrting something that look like this (of course its a bit more complex than this sample):
public class DoOnAll {
private List<IActionPerformer> actionPerformers;
public DoOnAll(List<IActionPerformer> actionPerformers) {
this.actionPerformers = actionPerformers;
}
public void callFromSomeWhere(String path) {
File f = new File(path);
List<File> list = Arrays.asList(f.listFiles());
for (File file : list) {
for (IActionPerformer action : actionPerformers) {
action.perform(file);
}
}
}
}
public interface IActionPerformer {
public void perform(File file);
}
public class SomePerformer implements IActionPerformer {
public void perform(File file) {
if (getFileType(file) = ".txt") {
doSomething
}
}
}
I have 2 questions:
Should I move the condition in SomePerformer to another method, boolean accept(File file) for example, and also add this method declartion to the interface?
If so, how would I "collect" all the accepted classes in DoOnAll? just go through the actionPerformers list and add all the accepeted to another list and then go through the list of accepted and .perform on them? Or is there another way usually used in the methodology?
Which ways are there for injecting the actionPerformrs list into the class?
I want to write independent implementations and define in a file, say xml file, which ones to inject into the list.
In answer to your second question, you should look into dependency injection. Java has a few good frameworks that can do this for you, for example:
Spring
Google Guice
Spring in particular allows you to define your application's components and dependencies in XML files. For examples see:
The IoC Container, in particular
Injecting Dependencies.
This last link has a subsection on constructor injection: creating java objects with dependencies supplied to their constructors, as your class DoOnAll requires.
WRT question 2: I agree with Dan, Spring or Guice.
WRT question 1: IMHO I would not create a conditional method as part of the interface. Either way you must call one method on each object, why call two? Let the object determine for itself if processing should be done. This also prevents any potential overhead in invoking multiple methods on the class. It also makes the calling method more straightforward.
Question 1. What you described is a chain-of-responsibility pattern. You can also check if a Performer can execute on file, of no - use next performer from a list. If no performes left - exception. You can use another method or make your perform method return true/false of throw exception if it can't perform.
Question 2. Use Spring in a simplest manner. Do it like:
ApplicationContext context = new ClassPathXmlApplicationContext("some_configuration.xml");
You can also try Google Guice.
General suggestions here:
Start simple (with what you have), and extend your interface when you have a use (case) for it. I'd just do if (accept(someFile)) perform(someFile); in an AbstractPerformer.performIfAccepted(File) method.
See other answers, I'm no expert in this area.
1) First off keep it simple... I think you need to decide what it is you want to do. Is it to (a) give a first responder the chance to respond to the presence of a file of a certain type, (b) allow all possible responders for that type to respond or (c) to identify a single specific responder to a file type.
If:
a) See Peter Gwiazda's answer (IMO).
b) Similar to (a) but permit multiple responders in the chain.
c) Where there is always a specific responder to a file type, you could use a factory to obtain a specific instance based on the file type. This hides the specifics of the implementation. There are disadvantages in an IoC environment but the factory can still be populated using IoC if required.
2) Check out "Inversion of Control" metaphor in general and Spring in particular (as already suggested).
I am working with a log of events where there are about 60 different "types" of events. Each event shares about 10 properties, and then there are subcategories of events that share various extra properties.
How I work with these events does depend on their type or what categorical interfaces they implement.
But it seems to be leading to code bloat. I have a lot of redundancy in the subclass methods because they implement some of the same interfaces.
Is it more appropriate to use a single event class with a "type" property and write logic that checks type and maintain some organization of categories of types (e.g. a list of event types that are category a, a second list that are category b, etc)? Or is the subclass design more appropriate in this case?
First Approach:
public interface Category1 {}
public interface Category2 {}
public abstract class Event {
private base properties...;
}
public class EventType1 extends Event implements Category1, Category2 {
private extra properties ...;
}
public class EventType2 extends Event implements Category3, Category4 {
private extra properties ...;
}
Second Approach:
public enum EventType {TYPE1, TYPE2, TYPE3, ...}
public class Event {
private union of all possible properties;
private EventType type;
}
My personal opinion is that it seems like a single event object is what is appropriate, because, if I am thinking about it correctly, there is no need for using inheritance to represent the model because it is really only the behavior and my conditions that alter based on the type.
I need to have code that does stuff like:
if(event instanceof Category1) {
...
}
This works well in the first approach in that instead of instanceof I can just call the method on the event and implement "the same code" in each of the appropriate subclasses.
But the second approach is so much more concise. Then I write stuff like:
if(CATEGORY1_TYPES.contains(event.getEventType()) {
...
}
And all my "processing logic" can be organized into a single class and none of it is redundantly spread out among the subclasses. So is this a case where although OO appears more appropriate, it would be better not too?
I would go with the object per event type solution, but I would instead group commonly used combinations of interfaces under (probably abstract) classes providing their skeletal implementations. This greatly reduces the code bloat generated by having many interfaces, but, on the other hand, increases the number of classes. But, if used properly and reasonably, it leads to cleaner code.
Inheritance can be limiting if you decide to extend an abstract base class of a
particular Category interface, because you might need to implement another Category as well.
So, here is a suggested approach:
Assuming you need the same implementation for a particular Category interface method (regardless of the Event), you could write an implementation class for each Category interface.
So you would have:
public class Category1Impl implements Category1 {
...
}
public class Category2Impl implements Category2 {
...
}
Then for each of your Event classes, just specify the Category interfaces it implements, and keep a private member instance of the Category implementation class (so you use composition, rather than inheritance). For each of the Category interface methods, simply forward the method call to the Category implementation class.
Since I didn't really get the answers I was looking for I am providing my own best guess based on my less than desirable learning experience.
The events themselves actually don't have behaviors, it is the handlers of the events that have behaviors. The events just represent the data model.
I rewrote the code to just treat events as object arrays of properties so that I can use Java's new variable arguments and auto-boxing features.
With this change, I was able to delete around 100 gigantic classes of code and accomplish much of the same logic in about 10 lines of code in a single class.
Lesson(s) learned: It is not always wise to apply OO paradigms to the data model. Don't concentrate on providing a perfect data model via OO when working with a large, variable domain. OO design benefits the controller more than the model sometimes. Don't focus on optimization upfront as well, because usually a 10% performance loss is acceptable and can be regained via other means.
Basically, I was over-engineering the problem. It turns out this is a case where proper OO design is overkill and turns a one-night project into a 3 month project. Of course, I have to learn things the hard way!
It depends on if each type of event inherently has different behavior that the event itself can execute.
Do your Event objects need methods that behave differently per type? If so, use inheritance.
If not, use an enum to classify the event type.
Merely having a large number of .java files isn't necessarily bad. If you can meaningfully extract a small number (2-4 or so) of Interfaces that represent the contracts of the classes, and then package all of the implementations up, the API you present can be very clean, even with 60 implementations.
I might also suggest using some delegate or abstract classes to pull in common functionality. The delegates and/or abstract helpers should all be package-private or class-private, not available outside the API you expose.
If there is considerable mixing and matching of behavior, I would consider using composition of other objects, then have either the constructor of the specific event type object create those objects, or use a builder to create the object.
perhaps something like this?
class EventType {
protected EventPropertyHandler handler;
public EventType(EventPropertyHandler h) {
handler = h;
}
void handleEvent(map<String,String> properties) {
handler.handle(properties);
}
}
abstract class EventPropertyHandler {
abstract void handle(map<String, String> properties);
}
class SomeHandler extends EventPropertyHandler {
void handle(map<String, String> properties) {
String value = properties.get("somekey");
// do something with value..
}
}
class EventBuilder {
public static EventType buildSomeEventType() {
//
EventType e = new EventType( new SomeHandler() );
}
}
There are probably some improvements that could be made, but that might get you started.