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)
Related
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.
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.
I'm doing a very dumbed down ALife-esque application, and I which to have the following classes with the following inheritance relationship:
(Abstract)Lifeform <-- Plant
(Abstract)Lifeform <-- Animal
Plants and Animals share some states, and I'd ideally like this behavior to live in rudamentary form within Lifeform.
abstract class Lifeform
{
public static enum State
{
IDLE,
DEAD
}
protected void someMethodSomewhere()
{
....
state = State.IDLE; // this to be recognized by inherited creatures
....
}
protected State state;
}
class Plant extends Lifeform
{
public Plant() { state=new Plant.State(); }
public static enum State extends Lifeform.State // (can't)
{
FEEDING,
REPRODUCING,
}
}
class Animal extends Lifeform
{
public Animal() { state=new Animal.State(); }
public static enum State extends Lifeform.State // (can't)
{
FEEDING,
FORAGING,
FLEEING,
GROUPING,
REPRODUCING
}
// elsewhere in some method
public void someMethod()
{
switch(state)
{
case IDLE: (...) // from Lifeform.State
case FEEDING: (...) // from Animal.State
case DEAD: (...)
....
}
}
}
Is there a facility in the later (1.5+) java's that allow for something similar to this, or am I best off embedding this state hierarchy within it's own traditional class?
I don't think this is an enum problem as much as it is a state machine problem.
You have the name State which to me implies that you are actually working with a state machine. I would not use enum for this and actually model a proper state machine.
From the states that you have posted in your question, they imply a finite state machine as well. I think you are just going to implement some sort of state machine around these enums as an end result and should just go ahead and start where you are going to end up eventually.
I have used state machine compiler to great effect in the past to make creating and managing the state transitions simply.
Ragel looks like a good solution as well.
The only way you can do what you want is to roll your own pre-1.4 TypeSafe Enum
Before Java had enum as a type, I used a Type Safe Enum Pattern template in my IDE to create what was actually a richer implementation of what ended up in the language.
It is essentially just a Java class with final instance members and a private constructor and public final static instances of itself.
I will still warn that extending enum is not allowed for a very good reason and trying to work around it will probably give you more grief than it will solve.
Here is the solution I've used for years, in case it helps someone. I've rewritten it somewhat.
Note: It purposefully does not implement value support. This is not a difficult change, and frankly, I don't use them, so I pulled it out. I also rewrote it from my originally ancient version.
Note: I'm primarily supplying it here because it contains toString() support to yield the field name (no matter what you've used) from any subclass.
I've also specified field errors due to access restrictions to be a catastrophic (execution ending) error. You can modify this to be any exception handling you choose, but I would suggest you leave it as is.
package tgm.utils;
import java.lang.reflect.Field;
public abstract class InheritableEnum
{
protected InheritableEnum() {}
public String toString()
{
String returnStr = "Unknown InheritableEnum["+super.toString()+"]";
Field[] fields = this.getClass().getFields();
for (Field f : fields)
{
try
{
if (f.get(this) == this)
{
returnStr = f.getName();
break;
}
}
catch(IllegalAccessException e)
{
System.err.println("Illegal access on field["+f+"]");
e.printStackTrace();
System.exit(-1);
}
}
return returnStr;
}
}
Then you would use it similarly:
public class State extends InheritableEnum
{
public static final State DEAD = new State();
public static final State EATING = new State();
public static final State GROWING = new State();
}
I have a class MyObserver that listens to changes in Notifier. Notifier extends Observable and notify its events with notifyObservers(Object). The object passed as argument is always an instance of the same class. The problem is that each observer need to listen to diferent events. For example one observer needs to listen to state changed events and others to all types of events. How can I do this with observer pattern?
Thanks.
Use notifyObservers(Object arg) version and create some sort of "event type" object to stick in there. In your observing classes simply filter on the passed in event class.
public void update(Object observable, Object arg) {
if ( (MyEvent) arg.isEventX() ) { /* do stuff */ }
}
I think that the Java built-in implementation of the Observer Pattern is not suitable for your case.
In fact, the general Observer pattern is usable when just one Observable kind of events can arise. In the Observer Design Pattern, all the Observes get notified always.
So, in this case, you need to extend the general Observer pattern, by defining your own Observable interface, for example, this way:
public enum EventKind {
EVENT_A, EVENT_B, EVENT_C;
}
public interface Observable {
public void registerObserver(EventKind eventKind);
public void unregisterObserver(EventKind eventKind);
public void notifyObservers(EventKind eventKind);
}
Then you can just implement this Observable interface with internal lists for each kind of event to notify. You can still use the Java built-in Observer interface if you wish.
This approach has the following benefits:
You can flexibly add more kind of events
without affecting the code of the
Observers.
You can register any observer to any
event.
You update just the Observers
that are effectively interested in
each event.
You avoid "empty methods", "event type checking" and other
tricks on the Observers side.
If you can change the design a bit:
interface MyObserver {
public void stateChangeEvent();
public void otherEvent();
}
class MyObserverAdapter implements MyObserver {
public void stateChangeEvent() {
// some default implementation or no implementation.
}
public void otherEvent() {
// some default implementation or no implementation.
}
}
class MyStateChangeObserver extends MyObserverAdapter {
public void stateChangeEvent() {
// implement behavior specific to this class.
}
}
class MyOtherObserver extends MyObserverAdapter {
public void otherEvent() {
// implement behavior specific to this class.
}
}
Usage:
MyObserver stateObserver = new MyStateChangeObserver();
MyObserver otherObserver = new MyOtherObserver();
notifier.notifyObservers(stateObserver);
notifier.notifyObservers(otherObserver);
You can test for a state change by doing the following in the Observable class:
public void update(Observable o, Object arg)
{
if(o.hasChanged())
{
// do something
}
}
The observers that listen to anything don't need this test. This is probably the easiest way if you only want to listen for state changes.
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.