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.
Related
I am new to scala I have a bit of experience in java. In the pattern matching section of their website they mentioned that when a parameter is passed to a function different logic can be implemented based on the reference type of the parameter. If so then what would the behavior when a parameter which extends many classes and interfaces is passed to pattern match containing all those classes and interfaces that it implement?
If only the first class/interface is implemented what could be a work around to implement all the logic related to all the classes/interfaces that it implements?
Link to website.
You are correct that a match statement will execute only the first case that matches, it will not check or execute later matches (otherwise case _ would always be executed).
There is no "work-around" because this isn't a bug or a limitation, it is a very useful feature of the language.
It sounds as if you have a number of different traits each of which has different behaviour and you want to execute the behaviour for all the traits.
The best way to do this is to write separate functions to match against each trait (Sum Var etc.) and call them one by one on the Tree instance. You can make a sequence of these and use foldLeft to apply each of them in turn. Since your derive function returns a new Tree instance you need to be clear about which order you want to apply the operations.
It remains unclear to me why you have a single object that represents both a Var and a Const, so I suspect that there is a deeper problem with your data structures.
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);
For example, I have a class Employee, with functions getName() and pay(). The first function simply returns the persons name (an immutable property), but the second function changes the object significantly (so calling this second function from different threads is bad for example).
Is there a term for a function that do not alter an objects state such as getName()? All functions in an immutable class will have this property.
I don't think there is a globally esteblished terminology for such a function.
Maybe "side effect free" and "pure" are close to what you want, but they mean that the function does not alter any state (neither of the object you call it on, and nor of any other object).
The word "pure" comes from the functional programming world, and means that the return value a function only depends on the value of its parameters. In object oriented programming it is common to also consider the object you call it on as one of the input parameters, so that property getters can be seen as "pure" functions.
There is no special naming for that. The reasonable thing to expect is that a method named "getSomething()" should have no side effects. In addition to that, for an immutable property, it should always return the same result.
In other words: when you implement such methods, you write them in a way that confirms those rules. (that also somehow tells you to not do premature optimization by doing some lazy-init somewhere; to avoid side effects when calling the method the first time!)
For good or bad, Java doesn't have the idea of a "const" keyword that could be used to make it clear that a certain method is side-effect free.
Besides, from a design point of view: you should be looking into making your Employee class fully immutable. In the sense of: why should invoking a "pay" method change anything within the Employee object?! When I receive my salary, by bank account goes up, but me, the Employee, I don't change because of that!
In that sense: you could be searching the net for "Agile practices" by Robert Martin. He does an extended full scale OO design for a real-world Employee/Payroll application. (and hint: the C# version PDF seems to be available for free).
"Query" like in Command-Query-Separation principle.
which one of below is better or to be prefered
new Object();
Object.setValue1("1");
Object.setValue2("2");
Object.setValue3("3");
or
new Object("1","2","3");
(I assume you're talking about the design of your own classes, rather than how to use other already-designed classes.)
Neither is always "better," it depends on the nature of the object and (to an extent) on your preferred style.
If an object cannot have a meaningful state without some external information, then requiring that information in the constructor makes sense, because then you can't create instances with an invalid state.
However, having constructors that require as little information as possible is useful in terms of making the class easy to use in a variety of situations. If the class is such that a zero-arguments constructor is feasible and doesn't complicate the class, it's great in terms of supporting various use-cases, including cases where the instance is being built as part of parsing some other structure (JSON, XML, etc.).
There is also a third option that builds on the use of fluent interfaces
MyObject obj = new MyObject().setValue1("1").setValue("2").setValue("3");
I personally like this approach but if the number of parameters is short and known at the time of construction AND the varying possible combinations of parameters is short then I would take the route of parameters on the constructor. I think most would agree that 12 constructor overloads are an eye sore.
Depends on whether you know the values at the time of object construction.
If Yes, then use the constructor version if not then you will have to use the other version.
Ofcourse,Initialization through the Constructor version is faster because it involves just one function call over 3 set function calls and also it is more logical way.
Its always better performance to call in constructor If you know values already.
Then there is my preferred alternative. Thing is the name of some interface. It creates an anonymous class.
Thing createThing ( final int val1 , final int val2 , final int val3 )
{
return new Thing ( )
{
// can use val1, val2, val3
} ;
}
It all depends on the application.
Calling Parameterized constructor will be a good idea if at Compile time you know what values to be given to your variables, rather than calling Setters. Because you are calling 3 setter methods and in parameterized constructor, you are just passing to the cnostructor it self.
But if at compile time you don't know what values to be given then how can you call paramterized constructor.
But for initialization it will be better to call parameterized constructor.
There is a semantic difference. If (1) you are instantiating an object with an initial state. In (2) you are changing the state of an existing instance (3 times). It's a small difference but may become very important in more complex systems (especially if you rely on various JavaBean conventions). But still, neither one is wrong or better.
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.