How to extract commonality from two classes.. template method? - java

I have two classes
public class ABC {
public void test() {
Car a = new Car();
a.start();
}
}
public class DEF {
public void test() {
Car a = new Car();
a.start();
a.stop();
}
}
Now both these classes do pretty much the same thing, how can extract out the commonality, or what is the best way.. would a template method work.. where by i use an interface... and have one parent method that calls an abstract method that is implemented on the subclasses?... but that would mean that one class has a no operation in a method?

Yes you can use template method pattern here:
public abstract class Template {
public void test() {
Car a = new Car();
a.start();
if(shouldStop()) {
a.stop();
}
}
public abstract boolean shouldStop();
}
public class ABC extends Template {
public boolean shouldStop() {
return false;
}
}
public class DEF extends Template {
public boolean shouldStop() {
return true;
}
}
Here you are adding a hook to allow subclasses to stop if they wish. You can obviously extends this to include any other optional functionality.

I kind of depends on what else you have beyond this trivial example, but you could do something like this:
public class ABC {
public Car test() {
Car a = new Car();
a.start();
return a;
}
}
public class DEF extends ABC {
public Car test() {
Car a = super.test();
a.stop();
}
}

The template method is usefull when you have steps that should be shared for all subclasses.
Template Method Wiki
The basic structure is what you already said. An abstract class with some abstract methods which have to be implemented by subclasses.
Interfaces, in the other hand, defines an API, not a behavior. So it's useless in this case.

Okay, so you've got commonalities in the methods:
Car a = new Car();
a.start();
What you can do, is make an abstract class, that both of these classes extend.
public abstract class ParentClass
{
public void test()
{
Car a = new Car();
a.start();
}
}
Then from your subclasses, you can call: super.test();. This will call the method in the parent class, before returning to the current method and finishing off the subclass implementation.
Advantages of this method
Any common code in these classes can now be pulled out, and placed inside the ParentClass. This means no repetition of code, which is always good. It also means that your class has logical structure, provided the superclass functions appropriately. This, again, is considered good practice because it makes your code more semantically logical.
Disadvantages of this method
The ParentClass is the ONLY class that the other classes can extend. This is called Inheritance and multiple Inheritance is something that Java does not support, so keep this in mind. If your ABC also shared similar functionality with another set of classes, then you might want to re-think your class structure.

Generally, and as much as possible, I prefer to put common functionalities in external (and static) methods, mainly for two reasons (they are very slightly different and related):
I prefer avoiding to keep my "inheritance slot", I can inherit from just one class and I want to be greed in extending, using it when very necessary or in the appropriate case (see point 2);
Inheritance should be used only where there's a relation of "type of" between classes; anyway, I personally believe that in Java you could be coerced, in some cases, to use inheritance in a wrong way because the Java language doesn't offer a mechanism for sharing common functionalities (such as modules in ruby).

Related

Java polymorphism: finding the right design pattern

Disclaimer: I know there are a lot of questions about polymorphism out there, but I couldn't find a suitable answer for my problem. If your Google-fu is better than mine, please forgive the dupe.
I have a model using inheritance, such as in the example below.
public abstract class Base {
// ...
}
public class ConcreteA extends Base {
private String someString;
// ...
}
public class ConcreteB extends Base {
private boolean someBool;
// ...
}
And I also have a List<Base>, which is composed of objects that are either ConcreteAs or ConcreteBs.
I need to generate a graphical view for each object in the list, but the resulting element is not the same for ConcreteAs and ConcreteBs. From the example above, the view for ConcreteA would be a text field, while the view for a ConcreteB would be a check box.
How can I achieve this using OO principles?
The problem that you have is that you somewhere return a List<Base> when the caller must know the concrete type.
Usually this is caused because one tried to make a method more generic. E.g. if someone has this service methods
public List<ConcreteA> doSomethingA(){ ... }
public List<ConcreteB> doSomethingB(){ ... }
he might think it is a better idea to introduce a superclass, Base so that both methods can be substituted by
public List<Base> doSomething(){ ... }
This is a good idea if the caller is only interessted in a Base object. This means that ConcreateA and ConcreteB have some common behavior that the caller only depends on.
But in your case it seems that the caller needs the concrete type information that is not available anymore, because of the more generic method.
So you either must preserve or reconstruct the type information.
Preserve the type by using a custom return type instead of making the method generic
public class Result {
private List<ConcreteA> concreteA;
private List<ConcreteB> concreteA;
}
public Result doSomething();
Recunstruct the type information using instanceof
Reconstruct the type information by introcucing a visitor pattern.
Not a pattern - this is what abstraction is all about. Declare a method you want all subclasses of Base to implement and each must implement it in their own way.
Obviously you would pass parameters and/or get results of the methods.
public abstract class Base {
abstract void graphicalView();
}
public class ConcreteA extends Base {
#Override
void graphicalView() {
}
}
public class ConcreteB extends Base {
#Override
void graphicalView() {
}
}
public void test() throws IOException {
List<Base> bases = new ArrayList<>();
for ( Base b : bases ) {
b.graphicalView();
}
}
I think you're looking for Visitor Design Pattern.
From Wikipedia :
In object-oriented programming and software engineering, the visitor
design pattern is a way of separating an algorithm from an object
structure on which it operates. A practical result of this separation
is the ability to add new operations to extant object structures
without modifying the structures. It is one way to follow the
open/closed principle.
In essence, the visitor allows adding new virtual functions to a
family of classes, without modifying the classes. Instead, a visitor
class is created that implements all of the appropriate
specializations of the virtual function. The visitor takes the
instance reference as input, and implements the goal through double
dispatch.
In such cases, I usually use generics something like this
public abstract class Base <T extends Shape>{
public abstract T drawShape();
}
public class ConcreatA extends Base<Circle> {
#Override
public Circle drawShape() {
return null;
}
}
public class ConcreatB extends Base<Square> {
#Override
public Square drawShape() {
return null;
}
}
So now you can use list of Shapes

A class inheriting methods from two sources

It's hard to explain, but it's simple to show a snippet of Ruby code:
Have two modules that implement methods:
module Foo
def one
print "ONE!"
end
end
module Bar
def two
print "TWO!"
end
end
Have a class that includes them:
class Test
include Foo
include Bar
end
Now your class Test can call those two methods.
As far as I'm aware, there isn't something like this in Java. Close concepts would be:
Multiple inheritance
Which is not supported by Java.
Interfaces
They're method contracts - there is no implementation. Your class Test would need to implement the methods itself, and that's what I want to avoid. Simply for the sake of not writing the same code twice (I have several other classes, some of them may want to implement those methods too).
Abstract classes
I'd still need to inherit from two classes at the same time.
So what is the recommended solution here?
In Java 8 you could achieve this using default methods but that was never the intent of defaults so this may be bad advice:
interface Foo {
default void one () {
System.out.println("ONE!");
}
}
interface Bar {
default void two () {
System.out.println("TWO!");
}
}
class FooBar implements Foo, Bar {
}
public void test() {
FooBar fooBar = new FooBar();
fooBar.one();
fooBar.two();
}
However, I would like to reiterate what #Thomas said in his comment The need for multiple inheritance is often a sign of a flaw in the design.
The easiest solution is to create hierarchical inheritance as so :
public class foo
{
public void one()
{
System.out.println("ONE!");
}
}
public class bar extends foo
{
public void two()
{
System.out.println("TWO!");
}
}
class Test extends bar
{
//this class now has access to both methods from the two classes
}
Favour composition over inheritance. So your class would have references to both implementing classes.
MyClass {
ClassA
ClassB
}
Th alternative of subclassing twice, seems rather hacky to me and would lead to an unnecessarily complex inheritance tree.
Or with java 8's new static methods (as opposed to default which can be overridden). See comparator for examples.
interface X
{
static void foo()
{
System.out.println("foo");
}
}
interface Y
{
static void bar()
{
System.out.println("bar");
}
}
MyClass implements X, Y {
public static void main(String args[])
X.foo();
}
The interface name must be used as prefix, as static method is part of interface.
There are few solutions that might solve your case. You can use the Visitor Pattern or Strategy Pattern.
In both cases you will benefit from Interfaces and Composition.
Your class Test would need to implement the methods itself, and that's what I want to avoid.
Well, yes, but that "implementation" could just be a simple delegation (and your IDE can create the code for this wrapper automatically).
public String one(){
return foo.one();
}
The actual code can be in class Foo, and be shared (as in "used") among many classes.

Return a private class implementing an interface keeping the implementation private

Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO

Is It Accepted Or Legal To Do this

I have a method in a class say
// super class
public class Car{
public void printMe(Car c){
if(c instanceof BMW){
Utility.printString("Bmw");
}else if(em instanceof VOLVO){
Utility.printString("Volvo");
}else if(em instanceof AUDI){
Utility.printString("Audi");
}else {
Utility.printString("Kia");
}
}
// sub classes
public class Bmw extends Car{
}
public class Volvo extends Car{
}
public class Audi extends Car{
}
public class Kia extends Car{
}
}
Now here i have a different class that loops through a list of Cars and print the correct statement according to the type of the Car
public class AccessCars{
ArrayLists<Car> carsList = listOfcars();
for(Car car: carsList){
car.PrintMe(car);
}
}
In the loop above i call the printMe(Car c) method on car en give car as an argument. Is is legal to do that? And if not, what is the best way of doing it?
thanks for your answer
a better way will be:
public abstract class Car {
public abstract void printMe();
}
public class Audi {
#Override
public void printMe() {
Utility.printString("Audi");
}
this is the OOP way to do it - using polymorphism
note that Car is implicit argument for printMe()
I would advise against polymorphism in this case -- every class prints out a string in the same way. The behavior is constant -- only the value printed varies. As such, the correct approach (IMO) is a variable that's printed out by printMe, and each derived class just initializes the variable appropriately.
It's legal, but not very good design. Perhaps a better approach is to define an abstract method Car.getModel() and implement it in each subclass to return the appropriate value. After all, you don't want to have to change the code for Car every time you add a new subclass.
Um, you can do that ... but I think you're missing the point of inheritance and overriding methods:
public class Car{
void printMe()
{
System.out.println("I'm a Car!");
}
}
public class Audi extends Car{
void printMe()
{
System.out.println("I'm an Audi!");
}
}
for(Car car: carsList){
car.PrintMe()
}
You get the overriden methods. Each car will print its name.
That being said, this is a silly example just to show how that works.
You'd really declare the Car class abstract and have printMe() be abstract, unless you had some reason to ever instantiate Car directly.
It's generally not acceptable to do this; since you already have "specialized" classes, why not put the printMe method in these classes? In case you want to enforce the subclasses have their own version of printMe, just make the printMe method in the super-class as abstract.
On a side note, another thing you might be interested would be a Visitor pattern:
In object-oriented programming and
software engineering, the visitor
design pattern is a way of separating
an algorithm from an object structure
it operates on. A practical result of
this separation is the ability to add
new operations to existing object
structures without modifying those
structures. It is one way to easily
follow the open/closed principle.
Definetly not OK, to do it.
I would define an abstract method called .Print() on the super class in such a way every subclass of Car must override it, and have your own way of Printing. Just like many samples above!
It is legal, however, not best of practice.
instanceof is a heavy operation on runtime environment and as such should be avoided if possible. This is not needed here, as every Car instance do the same thing - print itself. Consider this example:
public class Car {
// do some great stuff here...
public abstract String printMe();
}
public class Audi extends Car {
// do some great stuff here...
public String printMe() {
return "Audi rocks!";
}
}
// same for the other car models...
now iterate on the Car collection and run printMe for each.

Implicit object type in Java?

This isn't exactly the definition of implicit type conversion, but I'm curious how many standards I'm breaking with this one...
I'm creating an abstract class in Java that basically casts its variables depending on a string passed into the constructor.
For example:
public abstract class MyClass {
Object that;
public MyClass(String input){
if("test1".equals(input){
that = new Test1();
}
else{
that = new Test();
}
}
public void doSomething(){
if(that instanceof Test1){
//specific test1 method or variable
} else if(that instanceof Test2)}
//specific test2 method or variable
} else {
//something horrible happened
}
}
}
You see what I'm getting at? Now the problem I run into is that my compiler wants me to explicitly cast that into Test1 or Test2 in the doSomething method - which I understand, as the compiler won't assume that it's a certain object type even though the if statements pretty much guarantee the type.
I guess what I'm getting at is, is this a valid solution?
I have other classes that all basically do the same thing but use two different libraries depending on a simple difference and figure this class can help me easily track and make changes to all of those other objects.
You are right. This is a horrible way to achieve polymorphism in design. Have you considered using a factory? A strategy object? It sounds like what you are trying to achieve can be implemented in a more loosely-coupled way using a combination of these patterns (and perhaps others).
For the polymorphism of doSomething, for example:
interface Thing {
public void doThing();
}
class Test1 implements Thing {
public void doThing() {
// specific Test1 behavior
}
}
class Test2 implements Thing {
public void doThing() {
// specific Test2 behavior
}
}
class MyClass {
Thing _thing;
public void doSomething() {
_thing.doThing(); // a proper polymorphism will take care of the dispatch,
// effectively eliminating usage of `instanceof`
}
}
Of course, you need to unify the behaviors of Test1 and Test2 (and other concrete Thing classes, present and planned) under a set of common interface(s).
PS: This design is commonly known as Strategy Pattern.
I would create a separate class file. So you would have something like this:
1. You abstract "MyClass"
->within "MyClass" define an abstract method call doSomething...this will force the specific implementation of the method to it's subclasses.
2. Test1 would be the implementation of MyClass which would contain the implementation of the doSomething method
3. Create a utility class that does the check "instanceOf" that check should not be in the constructor it belongs in another class.
So in the end you would have 3 class files an Abstract Class, Implementation of the Abstract and a Class that does the "instanceOf" check. I know this sounds like a lot but it's the proper way to design, for what I think you are attempting to do. You should pick up a design patterns book, I think it would help you a lot with questions like these.
The Open-Closed principle would be better satisfied by moving the object creation outside of this class.
Consider changing the constructor to accept an object that implements an interface.
public MyClass {
public MyClass( ITest tester ) { m_tester = tester; }
public void doSomething(){ m_tester.doTest(); }
}
This makes it possible to change the behavior of the class (open to extension) without modifying its code (closed to modification).
The better way to do this is to create an interface which will specify a set of methods that can be guaranteed to be called on the object.
Here's an example:
public interface TestInterface
{
void doTest();
}
Now you can write your classes to implement this interface. This means that you need to provide a full definition for all methods in the interface, in this case doTest().
public class Test implements TestInterface
{
public void doTest()
{
// do Test-specific stuff
}
}
public class Test1 implements TestInterface
{
public void doTest()
{
// do Test1-specific stuff
}
}
Looks really boring and pointless, right? Lots of extra work, I hear you say.
The true value comes in the calling code...
public abstract class MyObject
{
Test that;
// [...]
public void doSomething()
{
that.doTest();
}
}
No if statements, no instanceof, no ugly blocks, nothing. That's all moved to the class definitions, in the common interface method(s) (again, here that is doTest()).

Categories

Resources