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.
Related
Could be there any flaw (from design perspective) when passing this instance of parent class into another object's constructor when new instance will be part of the original instance?
public class Order extends AbstractOrder {
private final OrderExecutionStrategy executionStrategy;
private Order() {
this.executionStrategy = new OrderExecutionStrategy(this);
}
// the implementation omitted for brevity...
}
I need to access data from parent instance in OrderExecutionStrategy class.
public class OrderExecutionStrategy extends AbstractOrderExecutionStrategy {
public OrderExecutionStrategy(final Order order) {
super(order);
}
#Override
public Optional<OrderPortion> executePortion(final BigDecimal newPrice, final TradeOrders orders) {
AssertUtils.notNull(orders, "orders");
AssertUtils.isGtZero(newPrice, "newPrice");
if (ComparisonUtils.equals(getOrder().getPrice(), newPrice)) {
final BigDecimal reaminingAmount = this.getOrder().summary().getRemainToFill();
if (ValidationUtils.isGtZero(reaminingAmount)) {
return Optional.of(new OrderPortion(this.getOrder().getId(), reaminingAmount));
}
}
return Optional.empty();
}
}
I can't see any design flaws in this.
However, there are a couple of caveats:
I am talking about design flaws, not implementation flaws.
"I am thinking that these two instances could negatively affect each other, an endless loop or something in that sense."
Those would be implementation flaws (aka bugs), not design flaws. A lot more context is required to check for that kind of thing.
You have only shown us a tiny part of the design, with few clues as to how this fits into the "bigger picture".
I would like to implement something like Strategy Pattern. I have generalized logic in Parent method, I need to pass specific logic (with casting etc..) into parent.
I have following classes:
class A{
public Object generateData(Function fetchData, AbstractForm form)
{
List<DataBean> dataBeans = (List<DataBean>) fetchData.apply(form);
//...
}
}
class B extends A{
void someMethod(AbstractForm form){
Function<AbstractForm, List<DataBean>> fetchFunction = new Function<AbstractForm, List<DataBean>>() {
//here goes form specific casting and other data fetch specific logic
return dataBeans;
}
super.generateData(fetchFunction, form);
}
}
Did I get the Idea of function correctly here?
Correct use of the Strategy pattern implies aggregation between a Context (in your case class A) and a Strategy (in your case an implementation of Function).
You can see the relationship in the image below (taken from the Gang of Four book, Design patterns: elements of reusable object-oriented software).
Below I've applied a traditional Strategy pattern approach to your problem. In this case I've made it so that Function.apply(AbstractForm) returns List<DataBean> to remove the need for casting. You could of course use generics to make Function more flexible.
Strategy
public interface Function {
List<DataBean> apply(AbstractForm form);
}
Context
public class A {
private Function fetchData; // strategy
public void setStrategy(Function fetchData) { // method for setting the strategy
this.fetchData = fetchData;
}
// precondition: fetchData != null
public Object generateData(AbstractForm form) {
List<DataBean> dataBeans = fetchData.apply(form); // using the strategy
return null; // whatever you want to return
}
}
In this case, extending class A is not neccessary as we can inject our Strategy (Function) using setStrategy(Function). However, we could always extend A to great an object with a predefined Strategy.
For example:
public class B extends A {
public B() {
setStrategy((form) -> null); // implement your concrete strategy here
}
}
Using a Factory Method
Since a Strategy for fetching the data is likely required and there may be no 'default' to use and may not ever change, the Factory method pattern could be used instead to enforce the creation of a Product (Function). Note class A is now abstract and includes a Factory method createFunction() which is then implemented in the subclasses (e.g. B) to create the Function.
The design for the factory method pattern can be seen in the UML below. In this case our Product is now what was previously our Strategy (Function) and the Creator is class A, with the ConcreteCreator being class B.
Creator
public abstract class A {
private Function fetchData; // product to be used
public class A() {
fetchData = createFunction(); // call factory method
}
protected abstract Function createFunction(); // factory method
// precondition: fetchData != null
public Object generateData(AbstractForm form) {
List<DataBean> dataBeans = fetchData.apply(form); // using the product
return null; // whatever you want to return
}
}
ConcreteCreator
public class B extends A {
#Override
protected Function createFunction() {
return (form) -> null; // return product
}
}
In this case the Product is fixed and not changable, but this could be overcome by mixing the two patterns together and including setStrategy(Function) again from class A in the first example.
I am implementing factory design pattern in java where I want to keep one overloaded method in abstract class. Will it violate the factory pattern concept?
Or please suggest whether this is right way to implement Factory design pattern ?
abstract class A{
void meth(int a);
void meth(int a,int b);
}
class Factory{
public static A factoryMethod(int a){
if(a==1){
return new Ob1();
}else{
return new Ob2();
}
}
}
class Ob1 extends A{
void meth(int a){}
void meth(int a,int b){}
}
To implement the Factory Pattern first you need to consider what the Factory will produce. Let's produce Vehicles.
public VehicleFactory {
public Vehicle newVehicle(String type) {
...
}
}
which will produce Vehicles according to the class hierarchy below.
public interface Vehicle {
public List<Door> getDoors();
}
public class Motorcycle implements Vehicle {
public List<Door> getDoors() {
return Collections.<Door>emptyList();
}
}
public class SportsCar implements Vehicle {
public List<Door> getDoors() {
return Collections.<Door>unmodifiableList(Arrays.asList(new Door("driver"), new Door("passenger"));
}
}
public class Hatchback implements Vehicle {
public List<Door> getDoors() {
return Collections.<Door>unmodifiableList(Arrays.asList(new Door("driver"), new Door("passenger"), new Door("back"));
}
}
Then your VehicleFactory method newVehicle(...) might look like
public Vehicle newVehicle(String type) {
if ("motorcycle".equals(type)) { return new Motorcycle(); }
if ("sports car".equals(type)) { return new SportsCar(); }
if ("hatchback".equals(type)) { return new Hatchback(); }
return null;
}
Now the main question is "Why would you want to do this?"
Sometimes you want a nice clean interface for building a lot of
related items. You give the related items an Interface and a Factory
to build them. This allows someone using this part of the software to
simply pull in the Interface class and the ItemFactory. They don't
see the individual details, which simplifies their code.
Since you hid the implementation details of all of the Vehicles in the above code, if you had a programming error (or wanted to add something), you can fix one of the Vehicles (or add a new Vehicle) to the factory and re-release the library (JAR file) containing the VehicleFactory.
You know that other people have been using the VehicleFactory methods, so you don't have to worry about their code breaking at compile time, and unless you were careless, you can also assure that it will work at runtime.
This is not the same as saying that the behavior won't change. The new implementations of Vehicle will be returned back, hopefully with fewer embedded bugs. Also, since they didn't ask for the "new vehicles" you might have added they won't see them, until they call newVehicle("station wagon") or something like that.
Also, you can change how the Vehicles are built up. For example, if you later decide that you don't want a simple "just construct it in one pass" implementation style, you could alter 'newVehicle(...)' like so
public Vehicle newVehicle(String type) {
Chassis chassis;
if ("motorcycle".equals(type)) {
chassis = new TwoWheelChassis();
} else {
chassis = new FourWheelChassis();
}
return new ComponentVehicle(chassis, getDoorCount(type));
}
where ComponentVehicle implements Vehicle and for some reason requires an explicit Chassis object.
--- update seeing the "number of methods" question in the comments ---
A Factory pattern is not really about the number of methods, but about one method having the ability to build an abstract thing out of one or more concrete things.
So in the example above, I could have
public VehicleFactory {
public Vehicle newVehicle(String type) { ... }
public Vehicle newRedVehicle(String type) { ... }
public Vehicle newBlackVehicle(String type) { ... }
}
And they would all be acceptible factory methods with respect to the type of the Vehicle, but they would not be factory oriented methods with respect to the color of the Vehicle.
To get a factory method that could handle Type and Color at the same time, the factory method
public Vehicle newVehicle(String type, String color) { ... }
might be added. Note that sometimes some combinations just don't make any sense, so it might not be worthwhile packing all factory methods down into a single factory method.
Any method in your factory object is not really a factory method unless it has the potential to return back more than one base type of the interface. Likewise it is not a factory method if you have to specify how to build the object outside of the method.
If you need to pass control of how to build a Vehicle to the client of your "it would have been a factory" method while providing some security they used it in a sane manner, you want the Builder pattern. An example of how a Builder Pattern differs can be seen in the client code below
VehicleBuilder builder = new VehicleBuilder();
builder.addDoor("driver");
builder.addDoor("passenger");
builder.paintVehicle("red");
Vehicle vehicle = builder.getVehicle();
Factory pattern is a vague term, no? There are Simple factories, Factory methods, and Abstract factories. I think you're talking about a Simple Factory here. https://www.codeproject.com/Articles/1131770/Factory-Patterns-Simple-Factory-Pattern
Here is an example of Java factory implementation.
Let's say we have a requirement to create multiple currencies support and code should be extensible to accommodate new Currency as well. Here we have made Currency as interface and all currency would be a concrete implementation of Currency interface.
Factory Class will create Currency based upon country and return concrete implementation which will be stored in interface type. This makes code dynamic and extensible.
Here is complete code example of Factory pattern in Java.
The Currency classes:
interface Currency {
String getSymbol();
}
// Concrete Rupee Class code
class Rupee implements Currency {
#Override
public String getSymbol() {
return "Rs";
}
}
// Concrete SGD class Code
class SGDDollar implements Currency {
#Override
public String getSymbol() {
return "SGD";
}
}
// Concrete US Dollar code
class USDollar implements Currency {
#Override
public String getSymbol() {
return "USD";
}
}
The Factory:
// Factory Class code
class CurrencyFactory {
public static Currency createCurrency (String country) {
if (country. equalsIgnoreCase ("India")){
return new Rupee();
}else if(country. equalsIgnoreCase ("Singapore")){
return new SGDDollar();
}else if(country. equalsIgnoreCase ("US")){
return new USDollar();
}
throw new IllegalArgumentException("No such currency");
}
}
// Factory client code
public class Factory {
public static void main(String args[]) {
String country = args[0];
Currency rupee = CurrencyFactory.createCurrency(country);
System.out.println(rupee.getSymbol());
}
}
Check out for more Java Factory pattern examples.
I have created a BicycleProducer interface which has different implementations: OffroadBicycleProducer, FastBicycleProducer and so on.
Each of these factories requires many parameters in order to produce a bicycle. I want to encapsulate these properties in a class and pass it to the produce method. However, the bicycles requires different properties - some may be the same - and I wonder how to do this properly. In the interface of BicycleProducer I have currently a method named produce which takes a parameter BicycleProducingContext which is a interface with all the common properties. And then you have implementations that implement it and add the necassary properties based on what type of bicycle it is. And then you would need to cast it in the produce method....but I don't know. It seem somewhat dodgy (it might not be) I feel.
Is this is a fine approach or should I do it in another way?
public interface BicycleProducer {
void produce(BicycleProducingContext context);
}
public class OffroadBicycleProducer implements BicycleProducer {
public void produce(BicycleProducingContext context) {
context = (OffroadBicycleProducingContext) context;
}
}
and
public interface BicycleProducingContext {
int numberOfBicycles();
void brand(String brand);
}
public class OffroadBycycleProducingContext implements BicycleProducingContext {
//..
}
I find two things sort of awkward about your proposed design:
To me, it looks like you may not need factories (i.e. your Producer classes) at all. Factories are useful when you need to construct an object whose type is not known at compile time. But since you're thinking of having separate factory classes for each type of bicycle (e.g. OffroadBicycleProducer), I assume you do know what kind of object you want to construct ahead of time.
Using a context class to make parameter passing less ugly is a good idea, but if you start creating separate context classes for each type of bicycle, then you end up in the awkward situation of having to know which context to construct as well as what data it requires -- which, if you have all that, you might as well just skip the intermediate step and construct the Bicycle right away.
If I was right in assuming that you do know what kind of object you need to construct ahead of time, then instead of using factories, I would go either with the builder pattern, or with plain old constructors. The constructor approach might look something like the following:
public abstract class Bicycle {
private int year;
private String color;
public Bicycle(BicycleProducingContext context) {
this.year = context.getYear();
this.color = context.getColor();
}
}
public class OffroadBicycle extends Bicycle {
private String terrainType;
public OffroadBicycle(BicycleProducingContext context) {
super(context);
this.terrainType = context.getTerrainType();
}
}
public class FastBicycle extends Bicycle {
private int maxSpeed;
public FastBicycle(BicycleProducingContext context) {
super(context);
this.maxSpeed = context.getMaxSpeed();
}
}
If you don't know what type of Bicycle you want to construct until runtime, then you can use the above approach with a single factory. For example:
public class BicycleFactory {
public static Bicycle constructBicycle(BicycleProducingContext context) {
if (context.getBicycleType().equals("OffroadBicycle")) {
return new OffroadBicycle(context);
} else if (context.getBicycleType().equals("FastBicycle")) {
return new FastBicycle(context);
} else {
throw new IllegalArgumentException("Encountered unrecognized Bicycle type: " + context.getBicycleType());
}
}
}
I hope I'm not over-simplifying your use-case, but it seems to me like the above should accomplish what you're looking for.
Having a chain of "instanceof" operations is considered a "code smell". The standard answer is "use polymorphism". How would I do it in this case?
There are a number of subclasses of a base class; none of them are under my control. An analogous situation would be with the Java classes Integer, Double, BigDecimal etc.
if (obj instanceof Integer) {NumberStuff.handle((Integer)obj);}
else if (obj instanceof BigDecimal) {BigDecimalStuff.handle((BigDecimal)obj);}
else if (obj instanceof Double) {DoubleStuff.handle((Double)obj);}
I do have control over NumberStuff and so on.
I don't want to use many lines of code where a few lines would do. (Sometimes I make a HashMap mapping Integer.class to an instance of IntegerStuff, BigDecimal.class to an instance of BigDecimalStuff etc. But today I want something simpler.)
I'd like something as simple as this:
public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }
But Java just doesn't work that way.
I'd like to use static methods when formatting. The things I'm formatting are composite, where a Thing1 can contain an array Thing2s and a Thing2 can contain an array of Thing1s. I had a problem when I implemented my formatters like this:
class Thing1Formatter {
private static Thing2Formatter thing2Formatter = new Thing2Formatter();
public format(Thing thing) {
thing2Formatter.format(thing.innerThing2);
}
}
class Thing2Formatter {
private static Thing1Formatter thing1Formatter = new Thing1Formatter();
public format(Thing2 thing) {
thing1Formatter.format(thing.innerThing1);
}
}
Yes, I know the HashMap and a bit more code can fix that too. But the "instanceof" seems so readable and maintainable by comparison. Is there anything simple but not smelly?
Note added 5/10/2010:
It turns out that new subclasses will probably be added in the future, and my existing code will have to handle them gracefully. The HashMap on Class won't work in that case because the Class won't be found. A chain of if statements, starting with the most specific and ending with the most general, is probably the best after all:
if (obj instanceof SubClass1) {
// Handle all the methods and properties of SubClass1
} else if (obj instanceof SubClass2) {
// Handle all the methods and properties of SubClass2
} else if (obj instanceof Interface3) {
// Unknown class but it implements Interface3
// so handle those methods and properties
} else if (obj instanceof Interface4) {
// likewise. May want to also handle case of
// object that implements both interfaces.
} else {
// New (unknown) subclass; do what I can with the base class
}
You might be interested in this entry from Steve Yegge's Amazon blog: "when polymorphism fails". Essentially he's addressing cases like this, when polymorphism causes more trouble than it solves.
The issue is that to use polymorphism you have to make the logic of "handle" part of each 'switching' class - i.e. Integer etc. in this case. Clearly this is not practical. Sometimes it isn't even logically the right place to put the code. He recommends the 'instanceof' approach as being the lesser of several evils.
As with all cases where you are forced to write smelly code, keep it buttoned up in one method (or at most one class) so that the smell doesn't leak out.
As highlighted in the comments, the visitor pattern would be a good choice. But without direct control over the target/acceptor/visitee you can't implement that pattern. Here's one way the visitor pattern could possibly still be used here even though you have no direct control over the subclasses by using wrappers (taking Integer as an example):
public class IntegerWrapper {
private Integer integer;
public IntegerWrapper(Integer anInteger){
integer = anInteger;
}
//Access the integer directly such as
public Integer getInteger() { return integer; }
//or method passthrough...
public int intValue() { return integer.intValue(); }
//then implement your visitor:
public void accept(NumericVisitor visitor) {
visitor.visit(this);
}
}
Of course, wrapping a final class might be considered a smell of its own but maybe it's a good fit with your subclasses. Personally, I don't think instanceof is that bad a smell here, especially if it is confined to one method and I would happily use it (probably over my own suggestion above). As you say, its quite readable, typesafe and maintainable. As always, keep it simple.
Instead of a huge if, you can put the instances you handle in a map (key: class, value: handler).
If the lookup by key returns null, call a special handler method which tries to find a matching handler (for example by calling isInstance() on every key in the map).
When a handler is found, register it under the new key.
This makes the general case fast and simple and allows you to handle inheritance.
You can use reflection:
public final class Handler {
public static void handle(Object o) {
try {
Method handler = Handler.class.getMethod("handle", o.getClass());
handler.invoke(null, o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void handle(Integer num) { /* ... */ }
public static void handle(BigDecimal num) { /* ... */ }
// to handle new types, just add more handle methods...
}
You can expand on the idea to generically handle subclasses and classes that implement certain interfaces.
I think that the best solution is HashMap with Class as key and Handler as value. Note that HashMap based solution runs in constant algorithmic complexity θ(1), while the smelling chain of if-instanceof-else runs in linear algorithmic complexity O(N), where N is the number of links in the if-instanceof-else chain (i.e. the number of different classes to be handled). So the performance of HashMap based solution is asymptotically higher N times than the performance of if-instanceof-else chain solution.
Consider that you need to handle different descendants of Message class differently: Message1, Message2, etc. . Below is the code snippet for HashMap based handling.
public class YourClass {
private class Handler {
public void go(Message message) {
// the default implementation just notifies that it doesn't handle the message
System.out.println(
"Possibly due to a typo, empty handler is set to handle message of type %s : %s",
message.getClass().toString(), message.toString());
}
}
private Map<Class<? extends Message>, Handler> messageHandling =
new HashMap<Class<? extends Message>, Handler>();
// Constructor of your class is a place to initialize the message handling mechanism
public YourClass() {
messageHandling.put(Message1.class, new Handler() { public void go(Message message) {
//TODO: IMPLEMENT HERE SOMETHING APPROPRIATE FOR Message1
} });
messageHandling.put(Message2.class, new Handler() { public void go(Message message) {
//TODO: IMPLEMENT HERE SOMETHING APPROPRIATE FOR Message2
} });
// etc. for Message3, etc.
}
// The method in which you receive a variable of base class Message, but you need to
// handle it in accordance to of what derived type that instance is
public handleMessage(Message message) {
Handler handler = messageHandling.get(message.getClass());
if (handler == null) {
System.out.println(
"Don't know how to handle message of type %s : %s",
message.getClass().toString(), message.toString());
} else {
handler.go(message);
}
}
}
More info on usage of variables of type Class in Java: http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
You could consider the Chain of Responsibility pattern. For your first example, something like:
public abstract class StuffHandler {
private StuffHandler next;
public final boolean handle(Object o) {
boolean handled = doHandle(o);
if (handled) { return true; }
else if (next == null) { return false; }
else { return next.handle(o); }
}
public void setNext(StuffHandler next) { this.next = next; }
protected abstract boolean doHandle(Object o);
}
public class IntegerHandler extends StuffHandler {
#Override
protected boolean doHandle(Object o) {
if (!o instanceof Integer) {
return false;
}
NumberHandler.handle((Integer) o);
return true;
}
}
and then similarly for your other handlers. Then it's a case of stringing together the StuffHandlers in order (most specific to least specific, with a final 'fallback' handler), and your despatcher code is just firstHandler.handle(o);.
(An alternative is to, rather than using a chain, just have a List<StuffHandler> in your dispatcher class, and have it loop through the list until handle() returns true).
Just go with the instanceof. All the workarounds seem more complicated. Here is a blog post that talks about it: http://www.velocityreviews.com/forums/t302491-instanceof-not-always-bad-the-instanceof-myth.html
I have solved this problem using reflection (around 15 years back in pre Generics era).
GenericClass object = (GenericClass) Class.forName(specificClassName).newInstance();
I have defined one Generic Class ( abstract Base class). I have defined many concrete implementations of base class. Each concrete class will be loaded with className as parameter. This class name is defined as part of configuration.
Base class defines common state across all concrete classes and concrete classes will modify the state by overriding abstract rules defined in base class.
At that time, I don't know the name of this mechanism, which has been known as reflection.
Few more alternatives are listed in this article : Map and enum apart from reflection.
Add a method in BaseClass which returns name of the class. And override the methods with the specific class name
public class BaseClass{
// properties and methods
public String classType(){
return BaseClass.class.getSimpleName();
}
}
public class SubClass1 extends BaseClass{
// properties and methods
#Override
public String classType(){
return SubClass1.class.getSimpleName();
}
}
public class SubClass2 extends BaseClass{
// properties and methods
#Override
public String classType(){
return SubClass1.class.getSimpleName();
}
}
Now use the switch case in following way-
switch(obj.classType()){
case SubClass1:
// do subclass1 task
break;
case SubClass2:
// do subclass2 task
break;
}
What I use for Java 8:
void checkClass(Object object) {
if (object.getClass().toString().equals("class MyClass")) {
//your logic
}
}