Java 8: looking for a design pattern to reduce code duplication - java

I'm having the following test classes. I'm wondering if there's a design pattern that can reduce the code duplication in the following scenario.
public abstract class BaseTestClass {
protected String color;
protected String type;
protected Product product;
abstract void setColor();
abstract void setClothType();
abstract Product createTheProduct();
#BeforeClass
public void setUp(){
// there're partial overlaps of "setup" for pants and shirts
}
#Test
public void doATest(){
testSomethingWithProduct(product);
}
#AfterClass
public void tearDown(){
// there're partial overlaps of "tearDown" for pants and shirts
}
}
public class TestBlueShirt extends BaseTestClass {
#Override
void setColor() {
this.color = "blue";
}
#Override
void setClothType() {
this.type = "shirt";
}
#Override
Product createTheProduct() {
setColor();
setClothType();
// create this.product based on color and type...
}
}
public class TestRedShirt extends BaseTestClass {}
public class TestBluePants extends BaseTestClass {}
public class TestRedPants extends BaseTestClass {}
...
You will find there's duplicated code when setting colors for the same type of cloth or when setting the type for the same color. I'm wondering how I can have a concrete class that can produce something like Class<T> (RedShirt, BlueShirt, RedPants, etc.), and based on Class<T>, I can directly implement #Test in the base class. So I can avoid code duplication as much as I can.
something like:
public abstract class BaseTestClass {
protected Product product;
abstract Product createTheProduct(Class<T> ...);
#BeforeClass
public void setUp(){
setUpBasedOnProduct(Class<T> ...);
}
#Test
public void doATest(){
testSomethingWithProduct(product);
}
#AfterClass
public void tearDown(){
tearDownBasedOnProduct(Class<T> ...);
}
}
import ...ClassGenerator
public class TestBlueShirt extends BaseTestClass {
#Override
createTheProduct(ClassGenerator.createClass("blue", "shirt"));
}
Thanks in advance!

You want to create an object, so what you're looking for falls under the umbrella of creational design patterns. I'm not sure if there's a perfect fit for your needs, but the Factory pattern matches some of your needs.
In a typical Factory pattern use case, you would supply a type (as a String or enumeration) to a method, and receive a matching object. Your logic would be a little more complex in that there will be several inputs and some branching logic to locate the correct type. For example, you can't just use a String "shirt" to get your object since the color is built into the types (you have RedShirt, BlueShirt, etc...).
As a final note, I'd consider asking yourself why RedShirt and BlueShirt have to be of different types. Rather than using a design pattern to get around the issue, I'd reconsider the original design. For example, you could use an Apparel extends Product class containing a color and type member, such that you can query that information regardless of the type of Apparel. Of course, use your best judgement depending on your situation.

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

Partial implementation of interface

I have an Inreface say
public interface myInterfacy {
String kilogramToGram();
Long litresTomiliLitres();
String inchesToMillimeters();
String ouncesToGrams();
}
I need to have multiple implementaton of this interface but I want the partial implementation of this inteface on different implementation,
As:
public class A implements myInterfacy {
public String kilogramToGram(){
//code
};
I don't want to give the definition of other methods.
}
public class B implements myInterfacy {
Long litresTomiliLitres(){
//code
};
I don't want to give the definition of other methods.
}
I thought that I can di it via using an abstract class, but I wonder If any other good approach is possible.
The answer is relatively simple but has many options.
You could
Make a number of partial interfaces and the one that "does it all" implements them all (not great)
You could make a number of "dummy" interfaces which throw an exception of unimplemented functionality. So, every proxy class would implement the full interface but throw runtime errors on unsupported methods (also not great)
Simply do nothing - literally. Implement the full interface and provide empty bodies (also really not great)
Or, you could encapsulate the functionality with a specific proxy to provide the given functionality.For example,
class FullyFunctional {
public void foo() {...}
public void bar() {...}
}
class PartiallyFunctional {
FullyFunctional ff;
public PartiallyFunctional(FullyFunctional ff) {
this.ff = ff;
}
// No foo...
public void bar() { ff.bar(); }
}
One way to do this, is with a convenience base class. This is however not really a good idea, because you won't get compile type checking to help ensure that you don't call unimplemented method.
public interface Converter {
public String kilogramToGram();
public long litresTomiliLitres();
public String inchesToMillimeters();
public String ouncesToGrams();
}
public abstract class AbstractConverter implements Converter {
#Override
public String kilogramToGram() {
throw new UnsupportedOperationException();
}
#Override
public long litresTomiliLitres() {
throw new UnsupportedOperationException();
}
#Override
public String inchesToMillimeters() {
throw new UnsupportedOperationException();
}
#Override
public String ouncesToGrams() {
throw new UnsupportedOperationException();
}
}
public final class A extends AbstractConverter {
#Override
public String kilogramToGram() {
//code
}
}
Follow interface-segregation-principle
Divide fat interface into granular small interfaces
Implement only require interface
One extreme case: I will declare four interfaces for four methods
public interface IKGToGram {
String kilogramToGram();
}
public interface ILitersToMilliLeters{
Long litresTomiliLitres();
}
public interface IInchesToMilliMeters{
String inchesToMillimeters();
}
public interface IOunceToGrams{
String ouncesToGrams();
}
Now you can implement whatever interface set you want to.
Have a look at explanation about interface segregation concept:
Interface Segregation Principle- Program to an interface

Java: method only callable by superclass

I would like to prevent a class from calling its own method. The method shall only be callable by its super class.
Right now, I cannot think of any way to achieve this (cleanly). But maybe someone knows a solution?
In code:
public abstract class A {
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
public class B extends A {
#Override
protected void foo() {
//do smth
}
private void barB() {
//must not be able to call foo() here
}
}
Edit: the explanation why I would like to do this:
A is lets say a vehicle. B can be a car or an airplane. The method foo() would be startEngines(). -> I want to make sure that the engines can only be started by calling the method barA().... does that make any sense?
There is a way to do it, but you need to use Google Error Prone. This is an extension of the Java compiler that aims to provide more and more helpful warnings and errors (similar to FindBugs and PMD, but with less false alarms). I can only recommend it, it has already helped us to find some bugs.
Specifically, it contains an annotation #ForOverride and an according compile-time check. This annotation is meant to be used for protected methods that the sub-class and any other class should not call, but only the defining class.
So using
public abstract class A {
#ForOverride
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
would exactly achieve what you want.
You can integrate Error Prone into most build systems like Maven and Ant. Of course, it won't help if somebody compiles your source without Error Prone (for example in Eclipse), but using it in a continous-integration system would still allow you to find such issues. The source code still stays compatible with regular Java compilers (provided you have error_prone_annotations.jar on the class path), other compilers will simply not do the additional checks.
this answer has a good hint.
add below method in your class (class B):
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[ste.length - 1 - depth].getMethodName();
}
and change the foo method in class B to this:
#Override
protected void foo() {
//....
if (getMethodName(0)=="barB"){
// tell you are not able to call barB
}
}
Considering your vehicle and engine scenario, I think you need to reconsider your design a bit.
Your vehicle could be a car, aeroplane, etc but car, aeroplane, ... each have separate engines and therefore different startEngine method. So declare your class vehicle as abstract like you did and class startEngine as abstract method . Next , subclass Vehicle and implement startEngine in them , now you can invoke startEngine on the subclass instances
abstract class Vehicle{
abstract void startEngine();
}
public class Car extends Vehicle{
public void startEngine(){
//implementation
}
public static void main(String[] arg){
Vehicle v=new Car();
v.startEngine();
}
}
Add Anonymouse inner class to barA method via Interface, so you will need to implement a method for foo() (functional interface). It won't be part of Class B.
you could put an interface as a member in the super class given to it via the constructor. the child class implements the method but can't call it except by making it static.
interface Foo {
void stopEngines();
void startEngines();
}
abstract class Base {
final private Foo foo;
public Base(final Foo foo) {
this.foo = foo;
}
private void barA() {
// do smth
foo.startEngines();
}
}
class Child extends Base {
public Child() {
super(new Foo() {
boolean engineRunning;
#Override
public void stopEngines() {
this.engineRunning = false;
}
#Override
public void startEngines() {
this.engineRunning = true;
}
});
}
private void barB() {
// can't call startEngines() or stopEngines() here
}
}
class Child2 extends Base {
public Child2() {
super(new Foo() {
#Override
public void stopEngines() {
stopEngines();
}
#Override
public void startEngines() {
startEngines();
}
});
}
static void stopEngines() {
// influence some static state?
}
static void startEngines() {
// influence some static state?
}
private void barB() {
// can call stopEngines() and startEngines(), but at least they have to be static
}
}
Of course, this is not really what you asked for, but about as much as you can do about it in Java, I guess.
Seeing the startEngines explanation, this solution might even suffice.
I guess you wouldn't care about the class calling its static methods, since they can only influence a static state, which is used seldom. The methods within the anonymous interface implementation can mutually call each other, but I guess that would be OK, since you only seem to be trying to prevent others to start the engines in some different way.
I guess this is similar to the problem AWT/Swing has with overriding the paint(Graphics g) method on a component (or onCreate(..) in Android Activities). Here you are overriding the paint method but you should never call it.
I think the best thing you can do is add documentation to the method to clarify that it should never be explicitly called by the subclasses OR re-evaluate your design.

Avoiding multiple implementations of the same method in different context

I have a simple design question. I am not sure how to design the following "situation" with respect to scalability and object-orientation.
interface IA {
void update();
}
class A implements IA {
public void update(){
updateInX();
updateInY();
}
private void updateInX(){
...
}
private void updateInX(){
...
}
}
The redundancy (updateInX(), updateInY()) seems like a bad design, but I have no idea how to improve it. I would appreciate your help!
This problem can be solved using Template method design pattern. You will basically define abstract class which contains abstract methods which has to be overriden and leave the computation itself on the abstract class. For instance
public abstract class Something {
public void update(){
updateInX();
updateInY();
printResult();
}
private void printResult() {
//print
}
protected abstract void updateInX();
protected abstract void updateInX();
}
This will make a child object implement only necessary methods and leave the computation on the base class.

Validate value objects (inheritance) in java

I want to validate my domain objects before I pass them on to a other part of the system. All the objects that I want to validate share the same interface. The problem is that I can't figure out how to write this in a good way. I don't want to move the validation inside my value object. But I don't want to be forced to do a instanceOf-check either.
An example:
public interface Vehicle {}
public class Car implements Vehicle {}
public class MotorBike implements Vehicle {}
public interface VehicleValidator {
void validate();
}
public class CarValidator implements VehicleValidator {
#Override
public void validate() {}
}
public class MotorBikeValidator implements VehicleValidator {
#Override
public void validate() {}
}
public void process(Vehicle vehicle) {
//TODO: validate vehicle
doSomething(vehicle);
}
In Scala I would have done something similar to http://debasishg.blogspot.se/2010/06/scala-implicits-type-classes-here-i.html
But those language constructs is not possible in Java.
This is a classic case for the Double Dispatch design pattern.
You need to add a tiny bit of call-back code in the vehicle, which will be dynamically bound to the appropriate method of the validator at runtime:
public interface Vehicle {
void validate(Validator validator);
}
public class Car implements Vehicle {
public void validate(Validator validator) {
validator.validateCar(this);
}
}
public class MotorBike implements Vehicle {
public void validate(Validator validator) {
validator.validateMotorBike(this);
}
}
public class Validator {
public void validateCar(Car car) {
// validate a car
}
public void validateMotorBike(MotorBike motorBike) {
// validate a motorbike
}
}
public void process(Vehicle vehicle) {
Validator validator = new Validator();
vehicle.validate(validator);
doSomething(vehicle);
}
As Oli Charlesworth wrote in his comment, this is usually done by Visitor pattern. http://en.wikipedia.org/wiki/Visitor_pattern
There is good java example on that wiki page.
Your best bet is a strategy pattern imo, however this won't get you away from doing instanceof/isAssignableFrom checks. However, if you build it well, at least you can abstract it out some, handle it generically, and not have to worry about adding additional checks if you add additional vehicle types.
I could go on to explain strategy patterns, but it's done better here: http://www.javacodegeeks.com/2012/04/strategy-pattern.html (with spring)
Many frameworks will have classes out-of-the-box to facilitate this.

Categories

Resources