While reading up on the Class Adapter pattern in Head First Design Patterns, I came across this sentence:
class adapter... because you need multiple inheritance to implement it, which is not possible in Java
Just to experiment, I tried the following:
interface MyNeededInterface{
public void operationOne(MyNeededInterface other);
public MyNeededInterface operationTwo();
}
public class ThirdPartyLibraryClass{
public void thirdPartyOp();
}
Suppose I create :
class ThirdPartyWrapper extends ThirdPartyLibraryClass implements MyNeededInterface{
#Override
public void operationOne(ThirdPartyWrapper other){
this.thirdPartyOp();
dosomeExtra();
}
#Override
public ThirdPartyWrapper operationTwo(){
int somevalue = doSomeThingElse();
return new ThirdPartyWrapper(somevalue);
}
}
In my code, I can use:
MyNeededInterface myclass = createThirdPartyWrapper();
myclass.operationOne(someobj);
...
Is this not the Class Adapter pattern?
The class adapter pattern is not possible in Java because you can't extend multiple classes. So you'll have to go with the adapter pattern which uses composition rather than inheritance.
An example of the adapter pattern through composition can be found below:
interface Duck
{
public void quack();
}
class BlackDuck implements Duck
{
public void quack() { }
}
class Turkey
{
public void gobble() { }
}
class TurkeyAdapter implements Duck
{
private Turkey t;
public TurkeyAdapter(Turkey t)
{
this.t = t;
}
public void quack()
{
// A turkey is not a duck but, act like one
t.gobble();
}
}
Now you can pass a Turkey to a method which is expecting a Duck through the TurkeyAdapter.
class DuckCatcher
{
public void catch(Duck duck) { }
}
By using the adapter pattern the DuckCatcher is now also able to catch Turkey(Adapter)s and Ducks.
Yes, you can create a class adapter with an interface as long as you're only wrapping a single adaptee. With multiple inheritance you could take two or more adaptees and wrap them into a single interface.
The full story in heads up is: class adapter pattern is impossible in Java just because Java does not provide multiple inheritance.
In their diagram, they show that the Adapter class subclasses both Target and Adaptee. Your example is (close to) the Object adapter pattern. The difference is that you implement the Target in your adapter class, rather then just subclassing the target (MyNeededInterface in your example)
GoF (Gang of Four) tells us about two major kinds of adapters:
A. Class adapters. They generally use multiple inheritance to adapt one interface to another. (But we must remember, in java, multiple inheritance through classes is not supported (for a good reason :) ). We need interfaces to implement the concept of multiple inheritance.)
B. Object adapters. They depend on the object compositions.
To illustrate the concepts, I'll present a simple example:
(source: book Java Design Patterns)
interface IIntegerValue
{
public int getInteger();
}
class IntegerValue implements IIntegerValue
{
#Override
public int getInteger()
{
return 5;
}
}
// Adapter using interface
class ClassAdapter extends IntegerValue
{
//Incrementing by 2
public int getInteger()
{
return 2 + super.getInteger();
}
}
// Adapter using composition
class ObjectAdapter implements IIntegerValue
{
private IIntegerValue myInt;
public ObjectAdapter(IIntegerValue myInt)
{
this.myInt=myInt;
}
//Incrementing by 2
public int getInteger()
{
return 2+this.myInt.getInteger();
}
}
class ClassAndObjectAdapter
{
public static void main(String args[])
{
System.out.println("Class and Object Adapter Demo");
ClassAdapter ca1=new ClassAdapter();
System.out.println("Class Adapter is returning :"+ca1.getInteger());
ClassAdapter ca2=new ClassAdapter();
ObjectAdapter oa=new ObjectAdapter(new IntegerValue());
System.out.println("Object Adapter is returning :"+oa.getInteger());
}
}
Console output:
Class and Object Adapter Demo
Class Adapter is returning :7
Object Adapter is returning :7
Class Adapters are kind of possible in Java by using single inheritance.
As an example from Design pattern for dummies, suppose we have to adapt AWT checkboxes to be used alongside with Swing checkboxes, we can write a class adapter for this.
The UI code in Swing to determine if a check box is checked is done with the isSelected method. But, AWT check boxes dont support isSelected(), they use getState() instead.
So we can write an adapter to wrap an SWT check box and adapt the getState() to isSelected()
public class CheckboxAdapter extends Checkbox
{
public CheckboxAdapter(String n)
{
super(n);
}
public boolean isSelected()
{
return getState();
}
}
Now we can handle AWT adapted check boxes as we would standard Swing check boxes when it comes to the isSelected method.
public void itemStateChanged(ItemEvent e)
{
String outString = new String("Selected: ");
for(int loopIndex = 0; loopIndex
<= checks.length - 1; loopIndex++){
if(checks[loopIndex].isSelected()) {
outString += " checkbox " + loopIndex;
}
}
text.setText(outString);
}
EDIT: True class adapter are not possible in Java, if they were we could inherit from multiple classes, which we want to mimic in an adapter class.
Also see http://www.journaldev.com/1487/adapter-design-pattern-in-java-example-tutorial for two examples in Java using Class Adapter and Object adapter, to achieve same result.
Related
I do have a service which needs to handle two types of meal.
#Service
class MealService {
private final List<MealStrategy> strategies;
MealService(…) {
this.strategies = strategies;
}
void handle() {
var foo = …;
var bar = …;
strategies.forEach(s -> s.remove(foo, bar));
}
}
There are two strategies, ‘BurgerStrategy’ and ‘PastaStrategy’. Both implements Strategy interface with one method called remove which takes two parameters.
BurgerStrategy class retrieves meals of enum type burger from the database and iterate over them and perform some operations. Similar stuff does the PastaStrategy.
The question is, does it make sense to call it Strategy and implement it this way or not?
Also, how to handle duplications of the code in those two services, let’s say both share the same private methods. Does it make sense to create a Helper class or something?
does it make sense to call it Strategy and implement it this way or not
I think these classes ‘BurgerStrategy’ and ‘PastaStrategy’ have common behaviour. Strategy pattern is used when you want to inject one strategy and use it. However, you are iterating through all behaviors. You did not set behaviour by getting one strategy and stick with it. So, in my honour opinion, I think it is better to avoid Strategy word here.
So strategy pattern would look like this. I am sorry, I am not Java guy. Let me show via C#. But I've provided comments of how code could look in Java.
This is our abstraction of strategy:
public interface ISoundBehaviour
{
void Make();
}
and its concrete implementation:
public class DogSound : ISoundBehaviour // implements in Java
{
public void Make()
{
Console.WriteLine("Woof");
}
}
public class CatSound : ISoundBehaviour
{
public void Make()
{
Console.WriteLine("Meow");
}
}
And then we stick with one behaviour that can also be replaced:
public class Dog
{
ISoundBehaviour _soundBehaviour;
public Dog(ISoundBehaviour soundBehaviour)
{
_soundBehaviour = soundBehaviour;
}
public void Bark()
{
_soundBehaviour.Make();
}
public void SetAnotherSound(ISoundBehaviour anotherSoundBehaviour)
{
_soundBehaviour = anotherSoundBehaviour;
}
}
how to handle duplications of the code in those two services, let’s say both share the same private methods.
You can create one base, abstract class. So basic idea is to put common logic into some base common class. Then we should create abstract method in abstract class. Why? By doing this, subclasses will have particular logic for concrete case. Let me show an example.
An abstract class which has common behaviour:
public abstract class BaseMeal
{
// I am not Java guy, but if I am not mistaken, in Java,
// if you do not want method to be overriden, you shoud use `final` keyword
public void CommonBehaviourHere()
{
// put here code that can be shared among subclasses to avoid code duplication
}
public abstract void UnCommonBehaviourShouldBeImplementedBySubclass();
}
And its concrete implementations:
public class BurgerSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
public class PastaSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
The abstract factory pattern is useful when we have families of related classes, and we want to instantiate them without relying on the implementation. However, what's wrong with using the factory method pattern in such a situation?
Let's say that we want to construct cross-platform UI elements, e.g. TextBox and Button for Windows and macOS and treat them abstractly. This is the typical situation in which we use the abstract factory pattern, and we can do so by defining the following:
AbstractUIElementsFactory interface
WindowsUIElementsFactory implements AbstractUIElementsFactory
MacUIElementsFactory implements AbstractUIElementsFactory
TextBox abstract class
MacTextBox extends TextBox
WindowsTextBox extends TextBox
Button abstract class
MacButton extends Button
WindowsButton extends Button
and the application would decide which concrete factory to create (based on some OS discovery mechanism) and pass it to a UIApplication class, which instantiates a TextBox and a Button, and calls display on them (which are abstract methods that simply return a String).
The code for this situation:
package abstractFactory;
abstract class Button {
public abstract void display();
}
class MacButton extends Button {
public void display() {
System.out.println("macButton");
}
}
class WindowsButton extends Button {
#Override
public void display() {
System.out.println("winButton");
}
}
abstract class TextBox {
public abstract void display();
}
class MacTextBox extends TextBox {
#Override
public void display() {
System.out.println("macTextBox");
}
}
class WinTextBox extends TextBox {
#Override
public void display() {
System.out.println("winTextBox");
}
}
interface UICreatorAbstractFactory {
Button getButton();
TextBox getTextBox();
}
class MacFactory implements UICreatorAbstractFactory {
#Override
public Button getButton() {
return new MacButton();
}
#Override
public TextBox getTextBox() {
return new MacTextBox();
}
}
class WindowsFactory implements UICreatorAbstractFactory {
#Override
public Button getButton() {
return new WindowsButton();
}
#Override
public TextBox getTextBox() {
return new WinTextBox();
}
}
class UIApplication {
private UICreatorAbstractFactory factory;
UIApplication(UICreatorAbstractFactory _factory) {
factory = _factory;
}
public void displayUI() {
factory.getButton().display();
factory.getTextBox().display();
}
}
public class Main {
public static void main(String[] args) {
new UIApplication(new MacFactory()).displayUI();
}
}
This implementation allows us to get UI elements transparently from factory implementations and also UI elements implementations, which is largely why we would use the pattern.
Using the same TextBox, Button, and their derivatives, we can have a factory method implementation with two factory methods in the creator, UICreator, each of which returns an abstract UI element. And we derive the creator and make two specializations WindowsUICreator, and MacUICreator, and each of which returns the appropriate concrete UI element, as follows:
abstract class UICreator {
public void displayUI() {
getButton().display();
getTextBox().display();
}
protected abstract Button getButton();
protected abstract TextBox getTextBox();
}
class WindowsUICreator extends UICreator {
#Override
protected Button getButton() {
return new WindowsButton();
}
#Override
protected TextBox getTextBox() {
return new WinTextBox();
}
}
class MacUICreator extends UICreator {
#Override
protected Button getButton() {
return new MacButton();
}
#Override
protected TextBox getTextBox() {
return new MacTextBox();
}
}
public class Main {
public static void main(String[] args) {
new MacUICreator().displayUI();
}
}
What are the downsides of this design? I believe it provides the needed decoupling by not having to deal with any concrete classes, and also provides the proper extensibility in the sense that we can introduce new UI elements and give them new factory methods, or newly supported OSs and implement concrete creators for them. And if we can use the factory method pattern in the exact situation the abstract factory pattern was designed for, I don't understand why do we have it at all?
They are both about creating new objects but the factory method is used to create one product only while the Abstract Factory is about creating families of related or dependent products.
In the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition, whereas the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.
I would like to show you an image from Saurav Satpathy's blog here which quickly can explain why you want abstract factory over factory method at times.
The argument for dependency injection and collection of related objects makes a lot of sense and here is a coded example by a great creator The Refactoring Guru on Abstract Factory and here is his example on factory method. The main difference between the examples in my opinion is the abstract factory better depicts the complexity of factories that create multiple types of objects. Additionally, it effectively divides the code in more classes, making each class simpler to understand (but creating more classes in total, of course).
Keep in mind this is not a very in depth analysis as of now, I want to see other people's opinions on the matter and give it some time to think for myself. I may come back in a couple of days with an edit (currently a bit busy, but I sneaked a quick opinion for you)
Edit #1 Inheritance
"Favor object composition over class inheritance. Inheritance breaks encapsulation, implement abstract classes, do not inherit concrete classes! - The Gang of Four on Design Patterns"
So object inheritance if you read the GoF's book: "Design Patterns Elements of Reusable Object-Oriented Software" is discouraged, especially when systems become more and more complex or higher in scope. Edit influenced by #FelipeLlinares great point indeed.
I have an interface called Section and MapSection which extends section. I have a list of Sections and if it is a MapSection I need to do some additional processing. I can thing of two ways to handle this. I can add a boolean isAMapSection() to the Section interface but that leads to alot of isA.. if I add more types. The other way I could think of is instanceof check but my OOP senses think this is not great either.
curSection instanceof MapSection
which one of these is the right way? or is there another way?
As mentioned above by Oliver Charlesworth's comment, you could use a Visitor Design Pattern to give your code to do different actions depending on the type involved, without having to use a bunch of instanceof's or class equals.
For example, say you have two similar interfaces, Section and MapSection, where for grins will give MapSection one additional method:
interface Section {
void someMethod();
void accept(SectionVisitor visitor);
}
interface MapSection extends Section {
void additionalProcessingMethod();
}
We'll also give Section the accept(...) method to allow action by a Visitor of type SectionVisitor whose interface looks like:
interface SectionVisitor {
void visit(Section section);
void visit(MapSection mapSection);
}
The visit method will hold code that knows which methods to call depending on the type passed into it.
A very simple concrete example could look like:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class VisitorTest {
public static void main(String[] args) {
Random random = new Random();
List<Section> sectionList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Section section = random.nextBoolean() ? new ConcreteSection() : new ConcreteMapSection();
sectionList.add(section);
}
SectionVisitor visitor = new ConcreteSectionVisitor();
for (Section section : sectionList) {
section.accept(visitor);
}
}
}
interface Section {
void someMethod();
void accept(SectionVisitor visitor);
}
interface MapSection extends Section {
void additionalProcessingMethod();
}
interface SectionVisitor {
void visit(Section section);
void visit(MapSection mapSection);
}
class ConcreteSection implements Section {
#Override
public void someMethod() {
System.out.println("someMethod in ConcreteSection");
}
#Override
public void accept(SectionVisitor visitor) {
visitor.visit(this);
}
}
class ConcreteMapSection implements MapSection {
#Override
public void someMethod() {
System.out.println("someMethod in ConcreteMapSection");
}
#Override
public void additionalProcessingMethod() {
System.out.println("additionalProcessingMethod in ConcreteMapSection");
}
#Override
public void accept(SectionVisitor visitor) {
visitor.visit(this);
}
}
class ConcreteSectionVisitor implements SectionVisitor {
#Override
public void visit(Section section) {
section.someMethod();
}
#Override
public void visit(MapSection mapSection) {
mapSection.someMethod();
mapSection.additionalProcessingMethod();
}
}
Best way might be to add a method "additionalProcessing" to Section. Implement this method to do your additional processing in MapSection, and leave it blank in your other implementations
Sometimes it's fine to have an isXXX method (and the corresponding asXXX method is nice too), but it really depends on how open-ended your object hierarchy is.
For example in StAX the XMLEvent interface will have descendants that represent the different types of events that can come from an XML document. But the list of those types is closed (no-one's going to radically change the XML format any time soon) and very short (there are about 10 different types of events in the StAX API), so it's fine. These interfaces also define the primary nature of their implementations, you wouldn't realistically just tag an object with an XMLEvent interface like you do with Serializable or Iterable.
If your interface is more "behavioural" (for want of a better word), more optional (like Comparable) or too open-ended (like LayoutManager), things like the visitor or the strategy pattern may be more appropriate.
Judging just by the names Section and MapSection, your model seems to belong to the first category but really only you can make that decision. What I definitely wouldn't do is leave it to the client of the code to fool around with instanceof calls. One way or another the solution should be part of Section.
I want to implement FSM like below
First Level Most basic State is BASE_STATE. All
states derive from BASE_STATE.
Second Level, WAITING_STATE,
RUNNING_STATE, END_STATE, ... so on
(Derived from BASE_STATE. No new
functionality)
Third level, There are 2 groups
states (ACTIVE and PASSIVE),
One-on-one matching for all second level states
like
ACTIVE_WAITING_STATE , ACTIVE_RUNNING_STATE , ACTIVE_END_STATE, so on
PASSIVE_WAITING_STATE, PASSIVE_RUNNING_STATE, PASSIVE_END_STATE, so on
most functionalities are common for ACTIVE and PASSIVE states, just some small functions overrided. There is no problem until here. Problem is, All third level group have common functions. I mean, For example I have to implement 2 different increment() function one of is ACTIVE_xxx_STATEs, another one is PASSIVE_xxx_STATEs. How to do this without re-written for all states (eg. ACTIVE_WAITING_STATE , ACTIVE_RUNNING_STATE , ACTIVE_END_STATE, and also PASSIVE states)
To clearify my questions, my ugly sol'n. Problem is increment functions is same and re-written for all ActivexxxState (and also PassiveXXXState).
public class BaseState {
// Lots of functions
}
public class WaitingState extends BaseState{
// Lots of functions
}
public class RunningState extends BaseState{
// Lots of functions
}
public class EndState extends BaseState{
// Lots of functions
}
public Class ActiveWaitingState extends WaitingState {
// Few unique functions
private void increment() {
System.out.println("increment active");
}
}
public Class ActiveRunningState extends RunningState {
// Few unique functions
private void increment() {
System.out.println("increment active");
}
}
public Class ActiveEndState extends EndState {
// Few unique functions
private void increment() {
System.out.println("increment active");
}
}
public Class PassiveWaitingState extends WaitingState {
// Few unique functions
private void increment() {
System.out.println("increment passive");
}
}
public Class PassiveRunningState extends RunningState {
private void increment() {
System.out.println("increment passive");
}
}
public Class PassiveEndState extends EndState {
private void increment() {
System.out.println("increment passive");
}
}
I would make increment() a protected method in BaseState so it is implemented once.
I have written an article on using enums to build a state machine. This can avoid the need to create classes everywhere for each state and still support some inheritance.
In answer to your comment.
abstract class BaseState {
public abstract boolean isPassive();
public boolean increment() {
System.out.println("increment "+(isPassize() ? "passive" : "active");
}
}
class PassiveState {
public boolean isPassive() { return true; }
}
If you don't want to have multiple isPassive methods you could assume a class naming convention
public boolean isPassive() { return getClass().getSimpleName().startsWith("Passive"); }
I'm not sure to have fully understand your question. Anyway, I'll suggest you to model active/passive state like a property in your class rather then use inheritance.
Make your hierarchy something like:
public class BaseState {
boolean active; //active or passive
}
public class WaitingState extends BaseState {
}
...
If you share common behaviour in your state machine you have two possibilities to implement that.
1) You can add the common implementation to the base state, so it can be called by any state implementation that inherits from the base state. The visibility of these methods would be protected.
2) A better solution in my oppinion is that you move the common behaviour into its own class that is not related to the states class hierarchy at all.
So you can think about a strategy class that implements the common behaviour and is referenced by the base class and can be called by any state.
The second solution is better because it increases the testability of both, the state machine and the strategy class.
class A extends ApiClass
{
public void duplicateMethod()
{
}
}
class B extends AnotherApiClass
{
public void duplicateMethod()
{
}
}
I have two classes which extend different api classes. The two class has some duplicate
methods(same method repeated in both class) and how to remove this duplication?
Edit
Both ApiClass and AnotherApiClass are not under my control
Depending on what the code is you could do something like:
public class Util
{
public static void duplicateMethod()
{
// code goes here
}
}
and then just have the other two duplicateMethods call that one. So the code would not be duplicated, but the method name and the call to the Util.duplicateMethod would be.
If the code in the Util.duplicateMethod needed to access instance/class variables of the A and B class it wouldn't work out so nicely, but it could potentially be done (let me know if you need that).
EDIT (based on comment):
With instance variables it gets less pretty... but can be done. Something like:
interface X
{
int getVar();
void setVar(A a);
}
class A
extends ApiClass
implements X
{
}
class B
extends AnotherApiClass
implements X
{
}
class Util
{
public static void duplicateMethod(X x)
{
int val = x.getVal();
x.setVal(val + 1);
}
}
So, for each variable you need to access you would make a method for get (and set if needed). I don't like this way since it make the get/set methods public which may mean you are making things available that you don't want to be available. An alternative would be to do something with reflection, but I'd like that even less :-)
Sounds like a case for the "Strategy Pattern".
class A extends ApiClass {
private ClassContainingDupMethod strategy;
}
class N extends AnotherApiClass {
private ClassContainingDupMethod strategy;
public methodCallingDupMethod(){
strategy.dupMethod();
}
}
class ClassContainingDupMethod{
public dupMethod(){;}
}
Or is the dupMethod inherted from the Api classes?
Duplicate methods that rely on member variables imply duplicate member variables, too - and that starts to smell like too-large classes. What would those specific member variables, with the method(s), look like, if you were to extract them into their own class, and then compose that class into your other classes? Prefer composition over inheritance.
class BaseApiClass
{
public void duplicateMethod()
{
}
}
class ApiClass extends BaseApiClass
{
}
class AnotherApiClass extends BaseApiClass
{
}
class A extends ApiClass
{
}
class B extends AnotherApiClass
{
}
You need to combine the classes into one object and then all classes using th other two classes, modify their code to use the single class.