Using Composition and Implementation in State Design Pattern - java

I read this link enter link description here,
to learn State Desing Patern.
interface class:
public interface State {
void doAction();
}
onState class:
public class TVStartState implements State {
#Override
public void doAction() {
System.out.println("TV is turned ON");
}
}
offState:
public class TVStopState implements State {
#Override
public void doAction() {
System.out.println("TV is turned OFF");
}
}
TvContext Class:
public class TVContext implements State {
private State tvState;
public void setState(State state) {
this.tvState=state;
}
public State getState() {
return this.tvState;
}
#Override
public void doAction() {
this.tvState.doAction();
}
}
test Class :
public static void main(String[] args) {
TVContext context = new TVContext();
State tvStartState = new TVStartState();
State tvStopState = new TVStopState();
context.setState(tvStartState);
context.doAction();
context.setState(tvStopState);
context.doAction();
}
Now I have two questions :
1- why TVContext Class implements State and has Composition toghether ?
is a bug in OO ?
because for example Cat inherits from Animal class and has_a animal together (in this case).
2-If The final programmer in this TestClass pass context to context.setState() instead of tvStartState or tvStopState , Program successfully compiles but error in run_time.
For the second question in State Design Pattern, instead of inheritance, same name method can be used. but int Decoration Design Pattern not.

Why TVContext class implements State and has composition together?
The example is incorrect, TVContext should not implement interface State. From the UML diagram for State Design Pattern we can see that class Context only
compose an attribute that implements interface State.
If the final programmer in this TestClass pass context to context.setState() instead tvStartState or tvStopState , program successfully compiles but errors in run_time.
The reason it compiles is because context is implementing interface State, but it fails in run-time with a java.lang.StackOverflowError because function context.setState() is recursively invoking itself with no exit condition. Removing the interface State from TVContext class fix this issue.
In Decorator Design Pattern the intent is to add new behavior to the Component class. That is why inheritance is used to add new methods to the Component.
In State Design Pattern the intent is to change the behavior of the Context class. For example if we implement it using inheritance with an abstract class instead of the interface the operation on the concrete state classes need to override the operation defined in the abstract class. That is why an interface makes more sense in this case.

Related

What pattern should be used, strategy?

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();
}
}

If I can have multiple factory methods in a creator class, why would I ever need the abstract factory pattern?

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.

Implementation of Observer Pattern Based on UML diagram

Question
I'm having trouble understanding the following UML-diagram of the Observer pattern from the "Elements of Reusable Object-Oriented Software". Could anyone explain me why my Java implementation is wrong and what I have to change to implement it correctly?
UML-Diagram
Attempted (but wrong) implementation
public interface Subject {
public static final List<Observer> observers = new ArrayList<Observer>();
public void attach(Observer o);
public void detach(Observer o);
public void notifyObservers();
}
public interface Observer {
public void update();
}
public class ConcreteSubject implements Subject {
private String subjectState;
#Override
public void attach(Observer o) {
observers.add(o);
}
#Override
public void detach(Observer o) {
observers.remove(o);
}
#Override
public void notifyObservers() {
for (Observer o : observers) {
o.update();
}
}
public String getState() {
return subjectState;
}
public void setState() {
subjectState += "x";
}
}
public class ConcreteObserver implements Observer {
private ConcreteSubject subject;
public String observerState;
#Override
public void update() {
observerState = subject.getState();
}
}
One problem is that you have a static list of observers in Subject so all subjects share the same observers. However, the pattern requires that each individual subject has its own observers so put the list into ConcreteSubject and make it an instance field.
Another problem is that your ConcreteObserver has a field of type ConcreteSubject. It should, however, not know about the concrete implementation of Subject so the field should only have the type Subject.
Edit: Actually the UML diagram requires the concrete observer to know about the concrete subject in order to be able to call getState() so the above paragraph is not true in your case - this should not be a problem here.
However, in reality I would actually have another interface that extends Subject and hides the implementation of ConcreteSubject from the observer.
Edit 2:
As has been suggested you could also use an abstract class to handle the observers of a subject. That could be a class in between Subject and ConcreteSubject or even Subject itself but since Java doesn't support multiple inheritance I'd often use some other approach and make Subject just an interface.
The easiest implementation would then be to have ConcreteSubject maintain the list of observers but in a real world application you'd not want to have developers do that or rely on them implementing it correctly.
Instead you could use a central registry that maintains the list of observers for each subject and which the subject uses to inform its observers. Many dependency injection frameworks out there operate in a way like that, i.e. whenever a "subject" changes they will inform its observers about that event.

Are we using the adapter design pattern everytime we extend a class and implements its interfaces methods?

My understanding of the adapter design pattern is that we are allowing an interface from an existing class to be used as another interface.
So every time we extend or implement a class in java we are using the adapter pattern? So this bit of code here is using the adapter design pattern?
public class car extends flyingMachine{
void drive(){}
#override
void fly(){}
}
There is lots of information on the pattern online but nothing that clarifies this question for me.
No -- inheritance is not an adapter pattern.
Say you have your Car with your drive() method (which really should implement an interface say Moveable with the method drive()). Now there is some other class that take a parameter of Moveable.
public class MakeItSo
{
public void easeOnDown(Moveable thing)
{
thing.drive();
}
}
Now let's say you have a cool new class Spaceship provided by someone else, and it has a method warp(). And it doesn't implement Moveable, but you'd like to use the MakeItSo class. What to do?
This is where the adapter pattern can help. In such a case, you create a new class that implements (or it could extend, but that is very confusing in many cases) the Moveable interface, but is:
- Constructed using the Spaceship
- Allows the drive() method to call the warp() method
public class MoveableSpaceship implements Moveable
{
private Spaceship ship;
public MoveableSpaceship(Spaceship s)
{
ship = s;
}
#Override
public void drive()
{
ship.warp();
}
}
Now you can do:
Spaceship enterprise = getSpaceship(); //from wherever
MoveableSpaceship ncc1701 = new MoveableSpaceship(enterprise);
MakeItSo doIt = new MakeItSo();
doIt.easeOnDown(ncc1701);
So, even though MakeItSo.easeOnDown only knew about Moveable, and the Spaceship didn't implement Moveable, using the adapter pattern it is now possible to use the MakeItSo class with a Spaceship object via the adapter pattern.
Note: updated class to match a comment that I originally didn't interpret correctly.

State pattern java

I am learning design pattern in java
I was doing through some of links.I am trying to design a washing machine by state pattern
I have a query regarding the implementation of state design pattern
public interface State {
public void openLid();
public void closeLid();
public void start();
public void stop();
public void washing();
}
public class Idle implements State{
//implementing overidden methods
.......
}
public class Washing implements State {
//implementing overidden methods
.......
}
public class WashingMachine {
State state;
public WashingMachine(State state) {
this.state = new Idle();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
I want to know when switching between state between idle to washing the implementation there can be two ways which is saw over net
1.WashingMachine class implements State interface and switch state from Idle to washing or vice versa based on some condition
2.Idle and Washing class has WashingMachine as member variable.
Please any one can suggest I am a bit confused about the implementation part.
Before addressing your question, I prefer reviewing the idea of the pattern and propose you some little modifications in your code.
State pattern allows an object to alter its behavior when its internal state changes.
In your case, Idle and Washing are good candidates as states and WashingMachine a good candidate to bear the state object.
However, three remarks :
1) Methods provided by the states should be some actions which implementations differ according to under which state the object is.
In your declaration :
public interface WashingMachineState {
public void openLid();
public void closeLid();
public void start();
public void stop();
public void washing();
}
washing() is not a action but a state.
It is the start() action that changes the state from idle to washing.
In the state pattern, the object with a state is named the context.
In your case, the context is WashingMachine.
2) in the state pattern, the idea is that the context wants to perform some actions which the behavior changes according to the current state.
To achieve that, the context delegates its processings to its current state instance.
It avoid having many if - else if in the context (for each processing), and it allows also to reduce the complexity of the context because when you use the state pattern, you get families of behaviors : :
behaviors when we are in the idle state are located in the IdleState class.
behaviors when we are in the washing state are located in WashingState class.
and so for...
To perform the actions, state instances need the context (WashingMachine).
To address this question, you have two ways of doing :
Either storing the WashingMachine object as a field in the state instance or passing this as an argument when the context WashingMachine object delegates to the state the processing.
I propose you to use the stateless way.
So, when the startWashing() operation is called on a WashingMachine instance, the WashingMachine instance should delegate the processing to state.startWashing() by passing itself such as state.startWashing(this).
The state should provide as parameter a WashingMachine :
public interface WashingMachineState {
void openLid(WashingMachine machine);
void closeLid(WashingMachine machine);
void pushStartBtn(WashingMachine machine);
void pushStopBtn(WashingMachine machine);
}
3) Actually you defined two states : idle and washing.
These should be completed with a stopping state because some operations on the machine (opening the door, pushing the start btn for example...) have a specific behavior when the machine is in the "is stopping" state.
Note that with only two states, you may also wonder if the pattern is relevant.
Now, I can answer to your question.
I want to know when switching between state between idle to washing
the implementation there can be two ways which is saw over net
1.WashingMachine class implements State interface and switch state from Idle to washing or vice versa based on some condition
2.Idle and Washing class has WashingMachine as member variable.
WashingMachine and WashingMachineStates are collaborating but different things.
So they have to not rely on the same interface.
Adding WashingMachine object as fields of state subclasses is a possibility.
As explained, you can also pass the WashingMachine as parameter of the State methods.
Note that it is not directly the WashingMachine that performs the switch from a state to another one.
This is performed by the state.
And states should invoke WashingMachine.changeState() to perform it.
The WashingMachine could be :
public class WashingMachine {
private WashingMachineState state;
public WashingMachine() {
this.state = new Idle();
}
protected void changeState(WashingMachineState state) {
this.state = state;
}
public void openLid(){
state.openLid(this);
}
public void closeLid(){
state.closeLid(this);
}
public void pushStartBtn(){
state.pushStartBtn(this);
}
public void pushStopBtn(){
state.pushStopBtn(this);
}
public State getState() {
return state;
}
}
Explanations about modifications on WashingMachine :
changeState is more meaningful as setState when using state pattern.
changeState(State) could use the protected modifier to decrease the visibility of this method and of course state subclasses should be in the same package than WashingMachine. It is a implementation detail enabled in Java. With other OOP languages, you have other alternatives of course.
About switching from idle to washing, I think that it should be possible only in the IdleState state as pushStartBtn() is invoked.
Here is an example :
public class IdleState implements State {
public void openLid(WashingMachine machine){
...
}
public void closeLid(WashingMachine machine){
...
}
public void pushStartBtn(WashingMachine machine){
//do processing with machine to begin effectively the washing
...
machine.changeState(new WashingState());
}
public void pushStopBtn(WashingMachine machine){
...
}
}
I think that better choice would be to create
public enum State{IDLE,WASHING};
and use that. This enum could be named even WashingMachineState as the states you have mentioned are specified to washing machine only - they will not be reusable, so no point of interfaces here.
If you would want to share the same states between different devices, eg. WashingMachine and DishWasher then you could use
public interface Statefull{
public State getState();
public void changeState(State newState);
}
And let WashingMachine and DishWasher implement Statefull interface.
With Java 8's default interface implementation you could even include getter implemention in interface so no boilerplate code in implementing classes.
Okay, let's go through both of your ideas:
1.) Is the washing machine a state? No, definitely no. Then why would it need to implement the state interface?
2.) This almost works, but it makes the states not reusable (which for a small implementation like this isn't bad, but for something like a game, it's terrible). They can only be the states of a washing machine. What if I want to use these states for a dish washer?
What you should do:
Make an interface or class, something like StateManager, and make the WashingMachine implement this, then instead of using a concrete class, create a StateManager field in the states.
Example:
public abstract class StateManager {
public State state;
public void setState(State newState) {
state = newState;
newState.parent = this;
}
public State getState() {
return state;
}
}
State:
public abstract class State {
public StateManager parent;
// Whenever you want to set the object's state, use this
}
Example State:
public class WashingState extends State {
// your methods here
}
Example state manager:
public class WashingMachine extends StateManager {
// your methods here.
}
I changed everything zo classes instead of interface, because they make creating some objects easier (like if you want to make a dishwasher and a washing machine, then you can extract the washing part from them, and make a separate class for it)

Categories