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.
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'm creating a RTS game and one of the features is to construct differend kind of buildings. I'm finding a lot of repetition and I was thinking to extract it in helper method, but the problem is that every building is different object which inharits some propertyes from the main building class.
The building methods looks like this:
public static void buildDockyard(Base base) {
if (Validator.checkForBuilding(base, "Dockyard")) {
throw new IllegalStateException("Dockyard is already build");
}
Dockyard dockyard = new Dockyard("Dockyard");
int requiredPower = dockyard.requiredResource("power");
int requiredStardust = dockyard.requiredResource("stardust");
int requiredPopulation = dockyard.requiredResource("population");
Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
dockyard.setCompleteTime(dockyard.requiredResource("time"));
base.getBuildings().add(dockyard);
}
public static void buildHotel(Base base) {
if (Validator.checkForBuilding(base, "Space Hotel")) {
throw new IllegalStateException("Space Hotel is already build");
}
SpaceHotel spaceHotel = new SpaceHotel("Space Hotel");
int requiredPower = spaceHotel.requiredResource("power");
int requiredStardust = spaceHotel.requiredResource("stardust");
int requiredPopulation = spaceHotel.requiredResource("population");
Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
spaceHotel.setCompleteTime(spaceHotel.requiredResource("time"));
base.getBuildings().add(spaceHotel);
base.setCapacity(base.getCapacity() + spaceHotel.getCapacity());
}
I was thinking to refactor like this:
The helper method
private static void construct(Building building, Base base) {
int requiredPower = building.requiredResource("power");
int requiredStardust = building.requiredResource("stardust");
int requiredPopulation = building.requiredResource("population");
Validator.checkResource(base, requiredPower, requiredStardust, requiredPopulation);
updateResourceAfterBuild(base, requiredPower, requiredStardust, requiredPopulation);
building.setCompleteTime(building.requiredResource("time"));
}
Aimed result
public static void buildDockyard(Base base) {
if (Validator.checkForBuilding(base, "Dockyard")) {
throw new IllegalStateException("Dockyard is already build");
}
Dockyard dockyard = new Dockyard("Dockyard");
construct(dockyar, base);
base.getBuildings().add(dockyard);
}
The problem is that each building has unique properties and resource requirements and the main Building class doesn't know about them, so I can't use it as a parameter in the helper method.
All of this is happening in a static helper class for the Base class.
How would you refactor this code ?
Thank you in advance !
Your problems start with using static methods for everything. In an object oriented world you ideally have an object Base and it would have a non-static method addStructure(Struture structure) were Structure is an interface for example. Now you would have objects like Building and Dockyard which would implement Structure.
Implentation of addStructure would be something like this:
if (getBuildings().contains(structure)) {
throw new IllegalStateException(structure.name + " is already build");
}
if (validateStillHaveEnoughResourcesFor(structure)) {
throw new IllegalStateException(structure.name + " can not be added. Not enough resources");
}
getBuildings().add(structure);
Validating structure itself should not be in base. Validating how structure fits to the base should be in the base.
The best way to DRY in Java when making games is to have a clear understanding and terminology of your game. If you read any modern board game manual you will soon see that they will use exactly one word for one concept, like Turn, Round, Building, Player, Resource. This allows to form a rough structure: A Building costs a certain amount of Resource. If a player hasn't enough of Resource then tell him "We need more vespine gas.", etc. The clearer the picture, the DRY-er your Java and easier to create the necessary Classes for your code.
Parameters
If you end up with something like this:
public static void someFunction(Base base, Object param1, Object param2)
public static void someOtherFunc(Base base, Object paramA, Object paramB)
...
Then this is a strong hint that maybe both functions should be part of the Base class.
Enums
If you have a limited set of values then Java Enums can be fantastic to represent them, e.g. your Resource system:
public enum Resource {
POWER, STARDUST, POPULATION
}
Now you don't have to remember if you called it "stardust", "Stardust" or if you even still have a Resource like "stardust". Instead you can use int requiredPower = building.requiredResource(Resource.POWER);
Polymorphism
Let's suppose we have two classes, Building and StarHotel, with StarHotel being a specific kind of Building. Having an abstract class Building allows us to handle some general mechanics in a specific manner, like this:
public abstract class Building {
private ... cost;
private ... requirements;
private ...
// Std-Getter and Setter methods
public ... getCost() { return this.cost; }
}
EVERY Building has a cost, and requirements and other important variables. BUT we handled all the standard stuff of getting and setting these generic variables to a base class from which we now can extend other, more specific buildings. Thanks to the extends keyword you can get the Cost of a StarHotel Object without filling the StarHotel class with repetitive Getters and Setters.
public class StarHotel extends Building {
// Getter, Setter inherited from Building class
}
Interfaces
Java Interfaces allow you to define Interfaces which define methods. In laymen terms: This is useful, because every Class that implements an Interface must implement the method, unless the interface provides the default implementation.
public interface ResourceProvider {
void provideResourceFor(Base base); // A Resource Provider provides Resource for a base.
}
With this interface we have defined that if some Class implements ResourceProvider it has to specify how and what resources to provide for some Base object. Our interface does not care which Resource, which Base and even what provideResourceFor could mean, but as long as something implements ResourceProvider it has to provide the functionality.
Putting all together
Putting Enums, Interface and Polymorphism together, we can now create a StarHotel class that extends Building and implements ResourceProvider, providing 8 Food units and 2 Happiness units to our Base.
public class StarHotel extends Building implements ResourceProvider
public void provideResourceFor(Base base) {
base.addResource(Resource.FOOD, 8);
base.addResource(Resource.HAPPINESS, 2);
}
}
That might be much to take in, but hopefully it will give you a good direction where to look further.
Not sure if what I want is possible but I am trying to create an enum in which each member has its own inner class. These inner classes will all have the same name Context but will be implemented individually.
Ideally I would like them to be usable as such:
private handleType (MyEnum type) {
switch (type) {
case ENUM_VAL1:
MyEnum.ENUM_VAL1.Context context = new MyEnum.ENUM_VAL1.Context();
handleContext1(context);
break;
case ENUM_VAL2:
MyEnum.ENUM_VAL2.Context context = new MyEnum.ENUM_VAL1.Context();
handleContext2(context);
break;
case ENUM_VAL3:
MyEnum.ENUM_VAL3.Context context = new MyEnum.ENUM_VAL1.Context();
handleContext3(context);
break;
default:
break;
}
Open to other way of implementing this. But basically I need a switchable enum where each member has a "value" (1,2,3...) and also a means of associating said enums with a unique class with constructor.
EDIT: Some background. This is to be used between two services who communicate via JSON http requests. The requests will contain some metadata, one field of which is an integer that maps to the enum. The context is a POJO, but is different for each ENUM_VALUE. Essentially, the context will be constructed and serialized into JSON. This json will effectively be just a String field called context within the top level json request. On the receiving service, there will be a switch on ENUM_VALUE, where the context is decoded appropriately and then dispatched to its appropriate handler.
EDIT2: This enum will be shared between the two services.
EDIT3: Here is a more explicit explanation of what I am attempting to do.
MyServiceRequest:
public class MyServiceRequest {
String meta1;
String meta2;
int typeID;
String context;
}
generating request:
MyServiceRequest req = new MyServiceRequest();
req.meta1 = ...
req.meta2 = ...
req.typeID = MyEnum.ENUM_VALUE.getCode(); // int
MyEnum.ENUM_VALUE.Context context = new MyEnum.ENUM_VALUE.Context(); // factory would be fine as well
... // populate context
req.context = toJSON(context);
requestJSON = toJSON(req);
post(requestJSON);
decoding request:
MyServiceRequest req = ...
MyEnum type = new MyEnum(req.typeID);
switch(type) {
case ENUM_VALUE:
MyEnum.ENUM_VALUE.Context context = fromJSON(req.context, MyEnum.ENUM_VALUE.Context.class);
doSomething(context);
One think you could do instead is have your enum implement Supplier<Context>. Now each item would have to declare a get() method to create the individual Context sub type.
enum MyEnum implements Supplier<Context>{
FOO{ #Override public Context get(){ return new FooContext(); } },
BAR{ #Override public Context get(){ return new BarContext(); } }
}
which would make your client code much simpler:
private void handleType (MyEnum type) {
handleContext(type.get());
}
Why use an inner class?
You could simply have a field context that gets initialized with different values for each enum constant. Like:
public enum Whatever {
A(new AContext), B...
private final Context context;
private Whatever(Context context) {
this.context = context;
....
I wouldn't recommend a separate inner class for every enum, just a separate implementation. Something like below would probably be your best approach, then you don't have to use a switch statment. Because you can just call getContext() on your type variable:
enum MyEnum{
A(new Context(){
// my implementation
}),
B(new Context(){
// my other implementation
}),
;
private final Context context;
MyEnum(Context context){
this.context = context;
}
public Context getContext(){
return context;
}
public interface Context{
// do something
}
}
The most significant problem with what you describe is that classes scoped to individual enum elements do not have names that are resolvable outside that element. That makes it impossible to instantiate such a class via the new operator outside the enum value, or to declare any method outside the enum value that has that class as argument or return type.
But you can largely work around that by declaring an interface type for the inner classes to implement, and providing a factory method to serve in place of a constructor for obtaining instances. For example:
enum MyEnum {
ENUM_VAL1 {
class Context implements MyEnum.Context {
public void doSomething() {
System.out.println(1);
}
}
public MyEnum.Context createContext() {
return new Context();
}
},
ENUM_VAL2 {
class Context implements MyEnum.Context {
public void doSomething() {
System.out.println(2);
}
}
public MyEnum.Context createContext() {
return new Context();
}
};
interface Context {
public void doSomething();
}
public abstract Context createContext();
}
public class EnumScope {
private void handleContext1(MyEnum.Context context) {
context.doSomething();
}
private void handleContext2(MyEnum.Context context) {
context.doSomething();
}
private void handleType(MyEnum type) {
MyEnum.Context context = type.createContext();
switch (type) {
case ENUM_VAL1:
handleContext1(context);
break;
case ENUM_VAL2:
handleContext2(context);
break;
}
}
}
I think this is a bit dubious, however -- especially having methods specific to particular enum values that do not actually belong to those enum values. There is likely an altogether different approach that would serve you better, but you have described the problem too generically for us to suggest such an alternative.
Update
After considering your edits to the question and your subsequent comments, I am inclined to stick with my assessment that what you're proposing is a bit dubious.
Take a step back and consider the problem from a wider perspective. You are generating, serializing (to JSON), deserializing, and consuming requests of several types (distinguished, at present, by an ID code that appears within). It makes sense to represent each type of request with a class bearing the appropriate properties, including those of the varying context data of each type. If there are some intentional commonalities, then perhaps these should implement a common interface that describes them, or even extend a common base class.
With that done, the JSON serialization / deserialization is a solved (more than once) problem. Unless you like reinventing the wheel, I'm inclined to suggest Google GSON for this. I need to qualify that with an admission that I haven't much personal experience with GSON, but it's quite popular, and you'll see a lot of questions (and answers) about it here. You'll also find some good online tutorials.
Essentially what I'm trying to do is create a generic method that can take many different kinds of enums. I'm looking for a way to do it how I'm going to describe, or any other way a person might think of.
I've got a base class, and many other classes extend off that. In each of those classes, I want to have an enum called Includes like this:
public enum Includes {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
public String getUrlParam() {
return urlParam;
}
}
I've got a method that takes in a generic class that extends from BaseClass, and I want to be able to also pass any of the includes on that class to the method, and be able to access the methods on the enum, like this:
ApiHelper.Response<Offer> offer = apiHelper.post(new Offer(), Offer.Includes.VENDOR);
public <T extends BaseClass> Response<T> post(T inputObject, Includes... includes) {
ArrayList<String> urlParams = new ArrayList<String>();
for (Include include : includes){
urlParams.add(include.getUrlParam());
}
return null;
}
Is there a way to be able to pass in all the different kinds of enums, or is there a better way to do this?
---EDIT---
I've added an interface to my enum, but how can I generify my method? I've got this:
public <T extends BaseClass> Response<T> post(Offer inputObject, BaseClass.Includes includes) {
for (Enum include : includes){
if (include instanceof Offer.Includes){
((Offer.Includes) include).getUrlParam();
}
}
return null;
}
But I get an error on apiHelper.post(new Offer(), Offer.Includes.VENDOR); saying the second param must be BaseClass.Includes.
Enums can implement interfaces, so you can create an interface with these methods that you'd like to be able to call:
interface SomeBaseClass {
String getUrlParam();
void setUrlParam(String urlParam);
}
and then your enum can implement this interface:
public enum Includes implements SomeBaseClass {
VENDOR ("Vendor"),
OFFERS_CODES ("OffersCodes"),
REMAINING_REDEMPTIONS ("RemainingRedemptions");
private String urlParam;
Includes(String urlParam) {
this.urlParam = urlParam;
}
#Override
public String getUrlParam() {
return urlParam;
}
#Override
public void setUrlParam(String urlParam) {
this.urlParam = urlParam;
}
}
If you want to get really fancy, it's possible to restrict subtypes of the interface to enums, but the generic type declaration will be pretty ugly (thus hard to understand and maintain) and probably won't provide any "real" benefits.
Unrelated note regarding this design: it's a pretty strong code smell that the enum instances are mutable. Reconsider why you need that setUrlParam() method in the first place.
I have multiple services (in Spring MVC) that are children of a global Service. So I need to know about the best practice (or your opinions) with multiple methods with this example:
//Domain classes
public class MyParentObject{}
public class MyObj extends MyParentObject{}
//Services
public class MyParentObjectServiceImpl implements MyParentObjectService{
#Override
public MyParentObject findObjectByProp(String prop, String objectType){
//myCode (not abstract class)
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl implements MyObjectService{
private myObjType = "MyObj";
#Override
public MyObj findMyObjByProp(String prop){
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
And in this approach, I use calls like this:
MyObj foo = myObjService.findMyObjByProp(prop);
So I need to know if this approach is "better" or more apropiate that calling directly the parent method with the second parameter. E.g:
MyObj foo = (MyObj)myParentObjectService.findObjectByProp(prop, "MyObj");
..and avoiding the creation of second methods, more specific. It is important to know that the children services will be created anyway, because we have lot of code that is specific of a domain objects.
I have the idea that the first approach is better, because is more readable, but I need to support that decision with some documents, blog, or opinions to discuss this designs with my colleagues.
This looks like a tagged class hierarchy. It's difficult to comment on the value of this design in general without knowing the details. However, a slightly different approach that I would recommend is to generify your base class to gain a little bit of type safety.
In particular:
public /* abstract */ class MyParentObjectServiceImpl<T extends MyParentObject>
implements MyParentObjectService{
MyParentObjectServiceImpl(Class<T> type) { this.type = type; }
private final Class<T> type; // subclasses provide this
#Override
public T findObjectByProp(String prop){
//you can use type for object specific stuff
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl<MyObj>
// You might not need this interface anymore
// if the only method defined is findMyObjByProp
/* implements MyObjectService */ {
MyObjServiceImpl() {
super(MyObj.class);
}
#Override
public /* final */ MyObj findMyObjByProp(String prop) {
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
You definitely gain in type safety (casting will only appear in the base class), you get rid of the "tags" (the strings that identify the different objects) and possibly reduce the number of classes/interfaces required to implement the whole hierarchy. I successfully used this approach several times. Note that this works best if the base class is abstract. Food for thoughts.