Java design question.
I have an object that needs to maintain sets of say 4 types of widgets: active, inactive, invalid, potential. For each of these types, I have a series of methods that acts on each: say add, get, remove, etc.
My question is, would it be better to have a series of methods like this:
addInactive(Widget)
getInactive()
removeInactive(Widget)
addActive(Widget)
getInactive()
removeInactive(Widget)
addInvalid(Widget)
etc...
OR
Should I have an enum inside this class instead: WidgetStatus and then the consumer would pass in this enum when they need to perform an action. This would result in only 3 public methods instead:
add(Widget, WidgetStatus)
get(WidgetStatus)
remove(Widget, WidgetStatus)
On one hand, I like the first using specialized methods because it not only keeps down the number of parameters needed, but it also forces the consumer's hand to explicitly call the method they need. However, the latter option seems to keep the API simple and makes adding additional status types in the future a bit easier.
Thoughts?
With the enum you get a cleaner API and much easier maintenance if you want to change the states; there really is no good reason for the first approach.
WidgetStatus is attribute of widget, not a container. May be follow will be good for you
Widget.setActive(false);
add(Widget);
I would turn the enum or whatever into some Strategy Pattern that includes the behavior you mention above. Then your add/get/remove methods will simply delegate to the strategy to perform the action.
http://en.wikipedia.org/wiki/Strategy_pattern
Related
I'm building an app that needs to use multiple types of similar sensors. Since the sensors could also have different behaviours, or combinations of behaviours, I decided to use the decorator pattern.
In short, I have a hierarchy that looks like this:
So any of the concrete ISensorDecorator classes can decorate (wrap) any of the concrete IMeasureSensor classes, but since a concrete ISensorDecorator also is a concrete IMeasureSensor, they can wrap each other. So for example
IMeasureSensor sensor = new FilteredSensorDecorator(
new CalibratedSensorDecorator(
new AccelerometerSensor()
)
);
is a valid statement that declares a filtered and calibrated accelerometer sensor.
Now let's say I have a method called setCalibration() in CalibratedSensorDecorator. Obviously I can't call
sensor.setCalibration();
because IMeasureSensor doesn't have a setCalibration() method. And trying to use
((CalibratedSensorDecorator)sensor).setCalibration()
won't work either, since sensor is a FilteredSensorDecorator.
How can I get to the CalibratedSensorDecorator in this particular case, and more generally to any specific decorator in any "chain" of decorators? I don't want to store them as separate variables, I want to do it dynamically.
Since its a design question, there won't be any right answer, you need to make choice which could be good or not that good.
You shouldn't add a method for particular class since it will violate the Liskov substitution principle
Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
You can initialize the calibration in constructor CalibratedSensorDecorator and use it while executing your required function.
If that doesn't meet your requirement, then may be CalibratedSensorDecorator doesn't belong in your sensor hierarchy. Consider separating it and use Strategy pattern to decide which one to use.
Edit 1:
what I understand it doesn't say that you shouldn't add methods to subtypes?
Yes, you are right. It doesn't prohibit from adding methods but if the methods are changing the state of an Object, then it should be re-considered. All these patterns are just the guidelines which can be tweaked as per our needs.
To explain my rationale:
Imagine you have create the setCalibration() on CalibratedSensorDecorator. You have following way to expose CalibratedSensorDecorator to either internal developer or to external developer. You have created a Factory which just returns IMeasureSensor as follows:
public IMeasureSensor getCalibratedSensor(){
...
}
Now the user of your API simply gets this and is happy that his/her current code is working. But realizes that he/she missed to setCalibration() which was found after hours of debugging. Moreover he/she has to write the type checking and type casting code to make use of this feature, which might not be great for clean code.
You should try to keep your classes as immutable as possible so that the debugging and maintenance are at ease. There is no harm in recreating the object since the older will be garbage collected.
Again its just my suggestion, its your decision to carefully consider what's best for your use-case. You can still go ahead with your new approach to create the method if its mandatory and ensure proper documentation has been made to make user understand the usage.
While the answer by Sagar discusses some (valid) reasons for considering using another approach than the decorator pattern, I came up with a working solution for the actual problem of finding the correct decorator.
/**
* Walks the decorator hierarchy recursively from the outside in (excluding the final
* IMeasureSensor which is not a ISensorDecorator), and returns the decorator of the given class.
* If none can be found, null is returned.
*/
IMeasureSensor findDecorator(IMeasureSensor sensor, Class decoratorClass){
if( ISensorDecorator.class.isAssignableFrom(sensor.getClass()) ){
return (sensor.getClass() == decoratorClass)
? sensor
: findDecorator(((ISensorDecorator) sensor).getDecoratee(), decoratorClass);
}
else
return null;
}
The method ISensorDecorator.getDecoratee() simply returns the "decoratee", i.e. the IMeasureSensor that the decorator decorates.
public IMeasureSensor getDecoratee(){
return mMeasureSensor;
}
You can then use findDecorator() to find a (the outermost) decorator of a given type like this:
IMeasureSensor sensor;
...
CalibratedSensorDecorator s = (CalibratedSensorDecorator) findDecorator(sensor, CalibratedSensorDecorator.class);
My current IVR app uses a wrapper class with several methods to call a web service and then parse its results. Each class has a single "invoke" method which calls the web service, and then calls subsequent submethods to break up the parsing into logical chunks.
Whenever a new input argument is needed in one or more of the submethods, the previous developer would add it as an argument on the invoke, and then add it as an argument on the submethods.
Is this the proper way to do this, or would it be better to set a field on the class, and then reference that whenever necessary?
Instead of:
invoke (oldField1, oldField2, newField1)
submethod1 (results, oldField1, oldField2, newField1)
submethod2 (results, oldField1, oldField2, newField1)
Should it be:
invoke(oldField1, oldField2, newField1){
OldField1=oldField1
OldField2=oldField2
NewField1=newField1
}
submethod1(results)
submethod2(results)
Or even:
new (oldField1, oldField2, newField1){
OldField1=oldField1
OldField2=oldField2
NewField1=newField1
}
invoke()
submethod1(results)
submethod2(results)
Thanks!
The first solution allows making the object stateless, and allows using a unique instance for all the invocations, even in parallel.
The third one allows making the object stateful but immutable. It could be used for several invocations using the same set of fields, even in parallel (if made immutable).
Both of these solutions are acceptable. The less state an object has, the easiest it is to use it, particularly in a multi-thread environment.
The less mutable an object is, the easiest it is to use it.
The second one makes it a stateful mutable object, which can't be used by several threads (without synchronization). It looks less clean than the other two to me.
My general rule is to avoid statefulness in a service-oriented class whenever possible. Although Java doesn't really support functional programming per-se, the simplest and most scalable implementation is your first approach, which uses no member variables.
If your goal is to avoid frequent changes to method signatures, you could try to use a more generic field encapsulation:
public class Invoker {
public static void invoke(ResultContainer result, List<String> parameters) {
submethod1(result, parameters);
submethod2(result, parameters);
}
}
I would also recommend that you take a look at the Decorator design pattern for more ideas.
It depends on if your argument is data or identifying a mode/switch.
I suggest one argument for the data structure type and another argument that contains the enum types of different operations.
And then based on your enum type or mode of operation you can choose a strategy on which class to execute.
To restrict this increasing argument approach, you could provide an interface. And force the implementation to adhere to that.
I'm starting using Fluent Assertions and I like it a lot, but wonder if it's possible to extend the existing tests in a general way like this:
add method hasSizeAtLeast(int limit) in GroupAssert
add method startsWithIgnoringCase(String prefix) in StringAssert
use alternatives like x.either().isIn(someSet).or().isNull()
These are just examples what I could need soon. I can do some workaround for each of them, but then I lose the readability and the easy of use of the fluent interface.
My last example is meant to throw iff both x.isIn(someSet) and x.isNull() do.
Here is a post by the author about opening up his API for extending assertions on already handled types. Lesson #1 in particular discusses the change to un-finalize classes. The post also gives an example of sub-classing StringAssert as MyStringAssert.
However, it looks like you cannot extend classes such as StringAssert in a way that maintains the "fluency" of the API. The StringAssert class isn't final, but still it doesn't allow you to parameterize its type (i.e. the "this" type that's returned by methods in StringAssert itself) in subclasses. For example, let's say you add a method checkFoo in MyStringAssert. As you discovered, the following is invalid because the original StringAssert methods return StringAssert:
new MyStringAssert("abcd").contains("a").checkFoo(); // compile-time error!
You only can call your subclass's methods first, which is valid but kind of lame:
new MyStringAssert("abcd").checkFoo().contains("a"); // compiles
You might consider contacting the author, or even submitting a patch to his git project. A possible solution would be to add the parameterized type back into StringAssert, and also provide the StringAssert concrete type via an anonymous subclass within Assertions.assertThat(String), which is the recommended entry point anyway. Then, everybody else can subclass StringAssert as you described. I haven't tested this suggestion either, but it seems to make sense...
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I am maintaining some Java code that utilizes an interface (let's call it BunchOfConstants) to simply store an abundance of public static final Strings. Occasionally these string names change or string names are added / removed. (which causes a bit of a headache for maintanance)
The only current use for this interface is to compare to input later in a big ugly if/then construct like this:
if(BunchOfConstants.CONSTANT1.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}else if(BunchOfConstants.CONSTANT2.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}else if(BunchOfConstants.CONSTANT3.equals(whatImLookingFor)){
doSomeStuff(whatImLookingFor)
}
...
I thought it would be more elegant to create a class that implements Iterable or even a class that stores this data in a hashMap.
I can not figure out why the original developers decided to use an interface for this design as the interface is never actually implemented anywhere. Does anyone have any input?
Would you agree that an iterable class with these members as constants would be more appropriate?
Use enums. Then get myenum.values() and then apply a for-each loop over the values.
I would consider using enums instead as constants are not type safe (e.g., they are just ints, or strings, etc.).
This (having dedicated interface for storing constants) was a fairly common way of storing constants before the era of enums. (Pre Java 5 times.) It saved you the hassle of prefixing your constants with the containing class name. I personally never really liked this practice, but this is the reason people did it.
As for what it can be replaced with:
An enum and a switch/case construct. This requires the least modification but only has modest benefits in readability. It does give you type and value safety, plus you can get warnings out of your IDE if you forget to handle a possible value (no case for it and no default block either).
A properties file. This obviously only works if you don't want to branch based on your constant values. (I.e. if your constants don't have to appear in your source code.) This is important, otherwise you'd end up with a secondary set of constants and a properties file, which is as bad as it gets.
A doSomeStuff() factory. For this you have to wrap your doSomeStuff() implementations in separate operation classes and you can configure your factory either statically or from a properties file. (via a constant value->operation class mapping). This is the most "enterprisey" solution, which means that although it looks nice and is very flexible, a lot of the time it is an overkill.
I think this is a good candidate for enum
Well, this looks like the Constant Interface antipattern and maybe should not be used. Using an enum might be a way as suggested, or at least using a final class with private constructor.
If you want to have different implementations for doSomeStuff based on the input string, you might also consider using the strategy pattern, i.e. have a Map<String, Strategy> and then lookup the strategy for whatImLookingFor. If you found the strategy, execute its doSomeStuff, otherwise handle the "not found" case.
I would suggest you to use a property file to store all your constants. This way you can load your properties into a HashMap as you suggest in your question.
Note that property support is brought natively with java: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html
Well, enums are the way to go ... but if the 'dosomestuff' is semantically dependent upon the specific value then why not add a 'dosomestuff' method to the enum itself. That is one that this is really great about Java enums - they are not merely data but as all good objects they have semantics. Then you just loop over the enums invoking dosomestuff(whatIamLookingFor) and whatever happens happens.
Hard to say.
Yes, I agree, that it will be more elegant - at least for you. But think, what the next programmer will think about it. It will be even more complicated.
Previously mentioned strategy pattern and java's enum are definitely better solution, but since you are maintaining this code, I'm not sure if your boss will be happy with time consuming refactoring. My advice would be to use enums - not so big code change.
When I was programming a Form Validator in PHP, when creating new methods, I needed to increase the number of arguments in old methods.
When I was learning Java, when I read that extends is to not touch previously tested, working code, I thought I shouldn't have increased the number of arguments in the old methods, but overridden the old methods with the new methods.
Imagine if you are to verify if a field is empty in one part of the form, in an other and in yet an other.
If the arguments are different, you'll overload isEmpty, but, if the arguments are equal, is it right to use isEmpty, isEmpty2, isEmpty3, three classes and one isEmpty per class or, if both are wrong, what should I have done?
So the question is:
If I need different behaviors for a method isEmpty which receives the same number arguments, what should I do?
Use different names? ( isEmpty, isEmpty2, isEmpty3 )
Have three classes with a single isEmpty method?
Other?
If that's the question then I think you should use:
When they belong to the same logical unit ( they are of the same sort of validation ) but don't use numbers as version, better is to name them after what they do: isEmptyUser, isEmptyAddress, isEmptyWhatever
When the validator object could be computed in one place and passed around during the program lifecycle. Let's say: Validator v = Validator.getInstance( ... ); and then use it as : validator.isEmpty() and let polymorphism to it's job.
Alternatively you could pack the arguments in one class and pass it to the isEmpty method, although you'll end up with pretty much the same problem of the name. Still it's easier to refactor from there and have the new class doing the validation for you.
isEmpty( new Arguments(a,b,c ) ); => arguments.isEmpty();
The Open/Closed Principle [usually attributed to Bertrand Meyer] says that "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification". This might be the principle that you came across in your Java days. In real life this applies to completed code where the cost of modification, re-testing and re-certification outweighs the benefit of the simplicity gained by making a direct change.
If you are changing a method because it needs an additional argument, you might choose to use the following steps:
Copy the old method.
Remove the implementation from the copy.
Change the signature of the original method to add the new argument.
Update the implementation of the original method to use the new argument.
Implement the copy in terms of the new method with a default value for the argument.
If your implementation language doesn't support method overloading then the principle is the same but you need to find a new name for the new method signature.
The advantage of this approach is that you have added the new argument to the method, and your existing client code will continue to compile and run.
This works well if there is an obvious default for the new argument, and less well if there isn't.
Since java 5 you can use variable list of arguments as in void foo(Object ... params)
You will need to come up with creative names for your methods since you can't overload methods that have same type and number of arguments (or based on return type). I actually personally prefer this to overloading anyway. So you can have isEmpty and isEmptyWhenFoo and isEmptyWhenIHaveTheseArguments (well meybe not the last one :)
Not sure if this actually answers your question, but the best way to think about OO in "real life" is to think of the Nygaard Classification:
ObjectOrientedProgramming. A program execution is regarded as a physical model, simulating the behavior of either a real or imaginary part of the world.
So how would you build a physical device to do what you are trying to do in code? You'd probably have some kind of "Form" object, and the form object would have little tabs or bits connected to it to represent the different Form variables, and then you would build a Validator object that would take the Form object in a slot and then flash one light if the form was valid and another if it was invalid. Or your Validator could take a Form object in one slot and return a Form object out (possibly the same one), but modified in various ways (that only the Validator understood) to make it "valid". Or maybe a Validator is part of a Form, and so the Form has this Validator thingy sticking out of it...
My point is, try to imagine what such a machine would look like and how it would work. Then think of all of the parts of that machine, and make each one an object. That's how "object-oriented" things work in "real life", right?
With that said, what is meant by "extending" a class? Well, a class is a "template" for objects -- each object instance is made by building it from a class. A subclass is simply a class that "inherits" from a parent class. In Java at least, there are two kinds of inheritance: interface inheritance and implementation inheritance. In Java, you are allowed to inherit implementation (actual method code) from at most one class at a time, but you can inherit many interfaces -- which are basically just collections of attributes that someone can see from outside your class.
Additionally, a common way of thinking about OO programming is to think about "messages" instead of "method calls" (in fact, this is the original term invented by Alan Kay for Smalltalk, which was the first language to actually be called "object-oriented"). So when you send an isEmpty message to the object, how do you want it to respond? Do you want to be able to send different arguments with the isEmpty message and have it respond differently? Or do you want to send the isEmpty message to different objects and have them respond differently? Either are appropriate answers, depending on the design of your code.
Instead having one class providing multiple versions of isEmpty with differing names, try breaking down your model into a finer grained pieces the could be put together in more flexible ways.
Create an interface called Empty with
one method isEmpty(String value);
Create implemntations of this
interface like EmptyIgnoreWhiteSpace
and EmptyIgnoreZero
Create FormField
class that have validation methods
which delegate to implementations of
Empty.
Your Form object will have
instances of FormField which will
know how to validate themselves.
Now you have a lot of flexibility, you can combine your Empty implemenation classes to make new classes like EmptyIgnoreWhiteSpaceAndZero. You can use them in other places that have nothing to do with form field validation.
You don't have have have multple similarly named methods polluting your object model.