Inner class for each member of enum? - java

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.

Related

Passing reference to instance into another object when new object is part of original object?

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".

What is the recommended pattern for two classes with identical behaviours but different class constants? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I have two classes which have identical behaviour, except class SnakeCaseyMapper uses snake_case constant fields and class CamelCaseyMapper uses camelCase constant fields.
Before requiring two of these classes, my logic looked roughly like:
public class Mapper {
public static final String FIELD = "snake_casey_field";
// Lots of other constant fields ...
public Foo map(Bar bar) {
// Some logic that makes use of the constant FIELDs
}
}
public class ClassThatsDoingLogic {
var mapper = new Mapper();
var result = mapper.map(bar);
}
Now I require this same method, map(Bar bar) but with camelCase constants, as well as the original implementation with snake_case.
My idea was to make use of abstract classes:
public abstract class Mapper {
public String field; // Not instantiated here
// Lots of other member variable fields ...
public Foo map(Bar bar) {
// Some logic that makes use of the constant FIELDs
}
}
public class SnakeCaseyMapper extends Mapper {
public SnakeCaseyMapper() {
field = "snake_casey_field";
// Lots of other fields instantiated
}
}
public class CamelCaseyMapper extends Mapper {
public CamelCaseyMapper() {
field = "camelCaseyField";
// Lots of other fields instantiated
}
}
public class ClassThatsDoingLogic {
var snakeCaseyMapper = new SnakeCaseyMapper();
var result = snakeCaseyMapper.map(snakeCaseyBar);
var camelCaseyMapper = new CamelCaseyMapper();
var result = camelCaseyMapper.map(camelCaseyBar);
}
This way both classes use the same method logic in map() without duplicating the code. However, I think I lose the finality of the constant fields I had originally. Is there a way around this? Is there a way of handling this problem I'm missing?
As #Kayaman suggested, inheritance should be avoided, and in your case, it is all about parameterisation. If you can do it via configuration loading it would be great.
A solution in the middle, could be possibly to instantiate a private constructor with all the arguments needed, and then provide one public constructor that would call the private one, setting the arguments needed under condition. (Note: untested code in examples below)
public class Mapper {
enum MapperType {
CamelCase,
SnakeCase
}
// Never define a public property. Use setters
// and getters to modify them outside the class,
// preserving the encapsulation principle.
private MapperType mType;
private int mProperty1;
public Mapper(MapperType type) {
this(type, type == MapperType.CamelCase ? 100 : 200);
}
private Mapper(MapperType type, int mProperty1) {
this.mType = type;
this.mProperty1 = property1;
// More properties here
}
}
A deviation to this, would also be to use Factory-ish pattern (Note: take the definition with a grain of salt, as normally, a factory can be used in order to generate instances of different derived classes sharing the same base class).
public class Mapper {
enum MapperType {
CamelCase,
SnakeCase
}
private MapperType mType;
private int mProperty1;
public Mapper(MapperType type, int mProperty1) {
this.mType = type;
this.mProperty1 = property1;
// More properties here
}
}
Then, you can create a Factory "Wrapper" class for the initialization:
public static class MapperFactory {
public static Mapper instantiate(Mapper.MapperType type) {
// Dummy example. Notice that we change all parameters.
// a dispatch table can also be considered to avoid switching.
switch(type) {
case Mapper.MapperType.CamelCase:
return new Mapper(Mapper.MapperType.CamelCase, 100);
case Mapper.MapperType.SnakeCase:
return new Mapper(Mapper.MapperType.SnakeCase, 200);
}
}
}
and then, you can do:
Mapper m = MapperFactory.instantiate(Mapper.MapperType.CamelCase);
Consider though that, if you are just adding such a few parameters, such implementation is overengineering, just to show you an example. Use it only if you have LOTS of parameters for your objects and you want ti. In simple scenarios, just call the Mapper class with the appropriate parameters, or make a simple conditional check upon initialization.
Also, regarding the difference between snake_case and camelCase fields, you can use regex in order to distinguish and properly initialize upon condition, but my sense is that you are asking mainly for the proper code segmentation, rather than fields distinction based on the style they are written.
To add to my comments. Since inheritance can be used when there's different behaviour, this is definitely not the right place for it.
Below are 3 examples with "least effort", although they still require at least the amount of lines that you have fields in the mapper.
public class Mapper {
private final String FIELD;
private String FIELD2 = "defaultCamelCase";
private final String FIELD3;
public Mapper(boolean snakeCase) {
// This would work for final instance fields
FIELD = snakeCase ? "snakey_case_field" : "camelCaseField";
// or fields having default values
if(snakeCase) {
FIELD2 = toSnakeCase(FIELD2);
// or some kind of similar mechanism
}
// or final instance fields with a private constructor helper
// that returns either the parameter as-is, or converts it
FIELD3 = initField("fieldName", snakeCase);
}
private String initField(String field, boolean snakeCase) {
if(!snakeCase)
return field;
return Arrays.stream(field.split("(?=[A-Z])")).map(String::toLowerCase).collect(Collectors.joining("_"));
}
}

Code repetition vs readablility

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.

Best design pattern for a scenario

We have a class called Variable which represents a singlevalue or compound value. For example, it can hold an integer,or a boolean,or a String etc... (single valued) or some compound value which can be list of Strings, integers or other Variables.
We serialize these objects and in the stream all these values are represented as strings. Whenever we serialize or deserialize there is a type conversion happening.
There are also some optional features or ways you can fill values in these variables. For example you can define a Variable to be populated from a webpage - For a given Variable we query a cache to understand if it should be populated from a webpage. Whenever someone does getValue() on the Variable we populate the value.
We also want to track changes of some variables. For example, I can choose to record or do some action whenever the value of a variable is read or changed.
As you can see that this is a hierarchical structure because variable can contain other variables. We wanted to find the best way to solve this.
Currently we have only one class called Variable which has so many if/else conditions and the code is very complex.
For example, getValue() code does the following:
if(query the cache to see if it needs population from webpage)
do something
else(---)
do something
else(if read should be recorded-find from cache)
do something etc...
Is there any pattern to design my classes in such a way that all my population from webpage logic can go in to one class, tracking logic in some other class, type conversion logic in some other class etc... to make it more readable.
Chain of Responsibility Each chained element in the Composite gets to do it's bit, but you have to spend some time configuring the runtime structure just so.
Possibly just a Composite or Observer for the getValue() scenario (but sounds more like Composite to me).
EDIT:
One could argue that the implementation below is in fact a case of "Chain of Responsibility", as a composite variable will delegate the responsibility of setting values to its children.
END EDIT
Here's a simple example using Observer and Composite. NOT TESTED just to give you the general feel for the solution...
I have not implemented stuff like serializing/deserializing.
In this solution you have compound values and atomic values, and you can add some observer to be executed before value is set.
package dk.asj.variables;
public abstract class VariableBase {
public interface Observer {
void onSet(final Value val, final VariableBase var);
}
private Observer obs = null;
public void setObserver(final Observer obs) {
this.obs = obs;
}
public void setValue(final Value val) {
if (obs != null) {
obs.onSet(val, this);
}
internalSetValue(val);
}
protected abstract void internalSetValue(final Value val);
public abstract Value getValue();
}
package dk.asj.variables;
import java.util.List;
public interface Value {
int getIntValue();
String getStringValue();
List<Value> getCompositeValue();
}
package dk.asj.variables;
public class SimpleVariable extends VariableBase {
private Value val = null;
#Override
protected void internalSetValue(final Value val) {
this.val = val;
}
#Override
public Value getValue() {
return val;
}
}
package dk.asj.variables;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class CompoundVariable extends VariableBase {
final List<VariableBase> children = new LinkedList<VariableBase>();
public void addChild(final VariableBase c) {
children.add(c);
}
#Override
protected void internalSetValue(final Value val) {
for (int i = 0; i < val.getCompositeValue().size(); ++i) {
children.get(i).setValue(val.getCompositeValue().get(i));
}
}
#Override
public Value getValue() {
final List<Value> res = new ArrayList<Value>(children.size());
for (final VariableBase var : children) {
res.add(var.getValue());
}
return new Value() {
#Override
public int getIntValue() {
throw new RuntimeException("This is a composite value");
}
#Override
public String getStringValue() {
throw new RuntimeException("This is a composite value");
}
#Override
public List<Value> getCompositeValue() {
return res;
}
};
}
}
I'm not sure if this answers your question, however, this could lead to some new ideas, here is what I came up with in a similar situation:
I named these DynamicVariables. A dynamic variable may have a default value or be evaluated by a lamda (Java 8)/anonymous inner class (pre-Java 8).
Each variable has an evaluation context and can be evaluated only in a context - i.e. Session context or a Global context. Contexts fallback to each other and create an hierarchy, i.e. Session context falls back to a Global context. So the default variable constant or lambda value can be shadowed by a lambda or a constant defined in a context. In instance, session-scoped variables shadow out global vars when are accessed inside a session.
And this appeared to be quite a flexible approach - I even implemented a trivial dependency injection by introducing InjectionContext which is a thread-safe context holding an object being wired.
You might want to have a look at an example of how this is used in a deployment tool I'm currently developing. Configuration management and shared application logic there is built upon these variables. Code is under bear.context package, but it's rather raw at the moment.

Encapsulating properties in a property/context class

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.

Categories