Sunday, October 2, 2022
HomeJavaLearn how to use State Design Sample in Java? Merchandising Machine Instance

Learn how to use State Design Sample in Java? Merchandising Machine Instance


The state design sample is a behavioral sample, first launched by GOF of their class is e-book design patterns. State sample seems just like Technique sample but it surely helps in managing object state and thus enabling them to behave in another way in a distinct state. On this instance, we are going to take a well-known object-oriented design interview query, implementing Merchandising Machine in Java. Previously, we’ve got solved this downside with out utilizing any design sample, however right here we are going to use state design patterns to create a merchandising machine with totally different states.  This instance won’t simply provide help to to grasp the best way to implement State Design Sample in Java but additionally offers you expertise about when to make use of State Sample in your software. 

If you know the way merchandising machine works, you may divide its operation into primarily 4 states sold-out, idle, processing, and bought. Offered-out when the merchandising machine is simply began and never initialized, or all objects have already bought. Idle, when the merchandising machine is ready for the client to pick out an merchandise, Processing, as soon as the client has chosen merchandise and began inserting a coin, Offered when the client has paid the quantity.

We are able to use a State design sample to mannequin these states of merchandising machines. On this instance, we’ve got an summary class known as State to signify the state of Merchandising Machine, which supplies a default implementation of assorted strategies, which known as by Context (Merchandising Machine on this case), every of our State, like Idle, Processing, Offered, SoldOut then extends this summary class and overrides the strategy, which will be known as in these state.

All different strategies, which isn’t presupposed to be known as on these state, will do default operation, which will be both do nothing or throw an exception, as outlined in State summary class. Every State class retains a reference to Context, via which they’re related they usually additionally make state transition, I imply to vary the present state of Merchandising Machine. 

Learn how to Design Merchandising Machine in Java utilizing State Design Sample – Instance

Right here is our full code instance of implementing Merchandising Machine utilizing State Design patterns in Java. When Merchandising Machine begins, it is initially on the SoldOut state then it strikes to Idle, as soon as it is initialized with a default variety of Objects and default variety of cash.


Merchandising Machine additionally supplies a technique that’s current in State summary class like choose(Merchandise i), insert(Coin c), refund(), and many others, however they’re delegated to the present state. When prospects choose merchandise by calling choose(Merchandise i) on Merchandising Machine, it delegates to currentState.choose(i), which is legitimate if Machine is within the Idle state after which it is going to transfer to Processing however will throw IllegalStateException if known as on different states.

By the best way, I have never gone into the technical definition of State Design Sample however in case you are curious, you may all the time see these finest Java design sample programs to be taught all 24 GOF design Patterns and their fashionable implementations in Java.
How to use State Design Pattern in Java? Vending Machine Example

Now, let’s examine the code, its fairly just like our Merchandising Machine Downside Code however this time, I’ve used State Sample to unravel the issue. 
Information:

  • Coin.java
  • Idle.java
  • stock.java
  • Merchandise.java
  • NotSufficientChangeException.java
  • Processing.java
  • Offered.java
  • SoldOut.java
  • State.java
  • VendingMachine.java
  • VendingMachineTest.java

Coin.java
==========

public enum Coin {
    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);

    personal int worth;
    personal Coin(int worth){
        this.worth = worth;
    }

    public int worth(){
        return worth;
    }
}

State.java
============

import java.util.Checklist;

public class State {

    public void insert(Coin c){
        throw new IllegalStateException();
    }

    public Checklist refund(){
         throw new IllegalStateException();
    }

    public int select(Merchandise i){
         throw new IllegalStateException();
    }

    public Merchandise dispense(){
         throw new IllegalStateException();
    }

    public Checklist getChange() {
        throw new IllegalStateException();
    }
}

Idle.java
==========

public class Idle extends State{

    personal VendingMachine machine;

    public Idle(VendingMachine machine){
        this.machine = machine;
    }

    @Override
    public int select(Merchandise i) {
        if(machine.itemInvertory.getCount(i) >= 1){
            machine.currentItem = i;
            machine.setState(new Processing(machine));
        }else{
            System.out.println(i + " bought out, Please strive one other drink");
        }
        return i.getPrice();
    }

}
Offered.java
==========

import java.util.Checklist;

public class Offered extends State{
    personal VendingMachine machine;

    public Offered(VendingMachine machine){
        this.machine = machine;
    }

    @Override
    public Merchandise dispense(){
        if(machine.itemInvertory.isEmpty()){
            machine.setState(new SoldOut(machine));
        }
        machine.stability = machine.stability  - machine.currentItem.getPrice();
 
        machine.itemInvertory.take(machine.currentItem);
 
        Merchandise bought = machine.currentItem;
        machine.currentItem = null;
 
        return bought;
    }

    @Override
    public Checklist getChange(){
        Checklist change = machine.getChange(machine.stability);
        return change;
    }
}

SoldOut.java
==============

public class SoldOut extends State{

    personal VendingMachine machine;

    public SoldOut(VendingMachine machine){
        this.machine = machine;
    }

}

Stock.java
===============

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class Stock {
    personal Map retailer = new ConcurrentHashMap();

    public int getCount(I merchandise){
        Integer depend = retailer.get(merchandise);
        return depend != null ? depend : 0;
    }

    public void add(I merchandise){
        int depend = getCount(merchandise);
        retailer.put(merchandise, ++depend);
    }

    public void take(I merchandise){
        int depend = getCount(merchandise);
        retailer.put(merchandise, --count);
    }

    public boolean isEmpty(){
        return retailer.isEmpty();
    }

    boolean has(I i) {
        return getCount(i) > 0;
    }
}

Merchandise.java
==========

public enum Merchandise {
    COKE(70), PEPSI(80), SPRITE(90);

    personal int worth;

    personal Merchandise(int worth){
        this.worth = worth;
    }

    public int getPrice(){
        return worth;
    }
}

NotSufficientChangeException.java
==================================

public class NotSufficientChangeException extends RuntimeException {

    personal String message;

    public NotSufficientChangeException(String string) {
        this.message = string;
    }

    @Override
    public String getMessage() {
        return message;
    }

}

Processing.java
================

import java.util.Checklist;

public class Processing extends State{

    personal VendingMachine machine;

    public Processing(VendingMachine machine){
        this.machine = machine;
    }

    @Override
    public void insert(Coin c) {
        machine.coinInvertory.add(c);
        machine.stability = machine.stability + c.worth();
        if (machine.stability >= machine.currentItem.getPrice()) {
     
            if (machine.hasChange(machine.stability - machine.currentItem.getPrice())) {
                machine.setState(new Offered(machine));
            } else {
                System.out.println("Machine haven't got 
                  enough change, Please take refund");
            }
        }

    }


    @Override
    public Checklist refund() {
        machine.currentItem = null;
        machine.setState(new Idle(machine));
        Checklist change = machine.getChange(machine.stability);
        machine.stability = 0;
        return change;
    }

}

VendingMachine.java
=====================

import java.util.ArrayList;
import java.util.Checklist;


public class VendingMachine {
    personal State state;
    Stock itemInvertory = new Stock();
    Stock coinInvertory = new Stock();

    Merchandise currentItem;
    int stability;

    public VendingMachine(){
        state = new SoldOut(this);
        initialize();
    }

    public void insert(Coin c){
        state.insert(c);
    }
    public Checklist refund(){
        return state.refund();
    }
    public int select(Merchandise i){
       return state.select(i);
    }

    public Merchandise dispense(){
        return state.dispense();
    }

    public void setState(State newState){
        state = newState;
    }

    public Checklist getChange(){
        return state.getChange();
    }

    personal void initialize() {
       loadCoins();
       loadItems();
       this.state = new Idle(this);
    }

    personal void loadCoins(){
        for(Coin c: Coin.values()){
           coinInvertory.add(c);
           coinInvertory.add(c);
           coinInvertory.add(c);
           coinInvertory.add(c);
           coinInvertory.add(c);
       }
    }

    personal void loadItems(){
        for(Merchandise i: Merchandise.values()){
           itemInvertory.add(i);
           itemInvertory.add(i);
           itemInvertory.add(i);
           itemInvertory.add(i);
           itemInvertory.add(i);
       }
    }

    Checklist getChange(int stability) {
        Checklist change = new ArrayList();
        whereas(stability != 0){
            if(stability >= Coin.QUARTER.worth() && coinInvertory.has(Coin.QUARTER)){
                stability -= Coin.QUARTER.worth();
                change.add(Coin.QUARTER); coinInvertory.take(Coin.QUARTER);
         
            }else if(stability >= Coin.DIME.worth() && coinInvertory.has(Coin.DIME) ) {
                stability -= Coin.DIME.worth();
                change.add(Coin.DIME); coinInvertory.take(Coin.DIME);
         
            }else if(stability >= Coin.NICKLE.worth() && coinInvertory.has(Coin.NICKLE)){
                stability -= Coin.NICKLE.worth();
                change.add(Coin.NICKLE); coinInvertory.take(Coin.NICKLE);
         
            }else if(stability >= Coin.PENNY.worth() && coinInvertory.has(Coin.PENNY)) {
                stability -= Coin.PENNY.worth();
                change.add(Coin.PENNY); coinInvertory.take(Coin.PENNY);
            }
     
           if(coinInvertory.isEmpty() && stability >0){
               throw new NotSufficientChangeException("Not Enough 
                        Change for this buy");
           }
        }
 
        return change;
    }

    boolean hasChange(int change) {
        strive{
           Checklist cash = getChange(change);
     
           
           for(Coin c : cash){
               coinInvertory.add(c);
           }
     
        }catch(NotSufficientChangeException ex){
            return false;
        }  
        return true;
    }

}

VendingMachineTest.java

Right here is our take a look at program to check the code of VendingMachine which we’ve got carried out utilizing a State design sample. These exams will verify that whether or not state transitions work as anticipated or not. The code beneath makes use of JUnit annotation therefore you want JUnit 4.0 framework JAR information in your classpath. I’ve a few exams to purchase drinks with actual change and with extra change to see if our machine is working correctly or not.

In your follow, I’ve additionally added a few clean take a look at strategies like buyMultipleDrinks(), refund(), and buyAllDrinks(), you may implement these strategies to get some follow on writing JUnit take a look at circumstances

This UML diagram of State Design Sample may also provide help to undersand class construction and their relationship. 

State Design Pattern Example - Vending Machine in Java

.

import java.util.Checklist;
import org.junit.Check;
import static org.junit.Assert.;


public class VendingMachineTest {
    personal VendingMachine machine = new VendingMachine();

    public VendingMachineTest(){
        System.out.println("JUnit Framework calls 
           Constructor of take a look at class earlier than executing take a look at strategies");
    }

    @Check
    public void buyDrinkWithExactAmount(){
        int worth = machine.select(Merchandise.COKE);
        assertEquals(70, worth);
        assertEquals(Merchandise.COKE, machine.currentItem);
 
        machine.insert(Coin.QUARTER);
        machine.insert(Coin.QUARTER);
        machine.insert(Coin.DIME);
        machine.insert(Coin.DIME);
        assertEquals(70, machine.stability);
        assertEquals(7, (int) machine.coinInvertory.getCount(Coin.DIME));
        assertEquals(7, (int) machine.coinInvertory.getCount(Coin.QUARTER));
 
        Merchandise i = machine.dispense();
        assertEquals(Merchandise.COKE, i);
        assertEquals(4, (int) machine.itemInvertory.getCount(i));
 
        Checklist change = machine.getChange();
        assertTrue(change.isEmpty());
 
 
    }

    @Check
    public void buyDrinkWithMoreAmount(){
        int worth = machine.select(Merchandise.SPRITE);
        assertEquals(90, worth);
        assertEquals(Merchandise.SPRITE, machine.currentItem);
 
        machine.insert(Coin.QUARTER);
        machine.insert(Coin.QUARTER);
        machine.insert(Coin.QUARTER);
        machine.insert(Coin.QUARTER);
 
        assertEquals(100, machine.stability);
        assertEquals(9, (int) machine.coinInvertory.getCount(Coin.QUARTER));
 
        Merchandise i = machine.dispense();
        assertEquals(Merchandise.SPRITE, i);
        assertEquals(4, machine.itemInvertory.getCount(i));
        assertEquals(5, machine.itemInvertory.getCount(Merchandise.COKE));
 
        Checklist change = machine.getChange();
        assertEquals(1, change.measurement());
        assertEquals(Coin.DIME, change.get(0));
        assertEquals(4, machine.coinInvertory.getCount(Coin.DIME));
         
    }

    @Check
    public void buyMultipleDrinks(){
        
    }

    @Check
    public void refund(){
        
    }

    @Check
    public void buyAllDrinks(){
        
    }
}
That is all on Learn how to use State design patterns to implement a Merchandising Machine in Java. You possibly can see a transparent benefit by way of managing logic to vary states and implementing the totally different habits in numerous states in comparison with our earlier instance. I extremely advocate you implement Merchandising Machine or any state-oriented downside utilizing State design patterns in Java. It leads to each less complicated and environment friendly options. 


Different Object-Oriented Design Sample Tutorials from Javarevisited

  • 18 OOP Design Sample Interview Questions for knowledgeable Programmers (checklist)
  • 7 Greatest Java Design Sample programs for Novices (programs)
  • 20 Software program design Questions from Programming Interviews (checklist)
  • Learn how to implement Builder design sample in Java? (tutorial)
  • Distinction between Manufacturing unit and Summary Manufacturing unit Sample? (instance)
  • Learn how to implement Adapter sample in Java (adapter sample)
  • 10 OOP Design Precept Each Java developer ought to be taught (strong precept)
  • Learn how to implement Composite Sample in Java? (composite sample instance)
  • 7 Greatest Books to be taught the Design Sample in Java? (books)
  • Learn how to implement the Technique Design Sample in Java? (instance)
  • 20 System Design Interview Questions (checklist)
  • Learn how to implement Command Sample in Java (command sample)
  • Learn how to implement a Decorator design sample in Java? (tutorial)
  • Learn how to use Manufacturing unit methodology design sample in Java? (tutorial)
  • What’s the distinction between Manufacturing unit sample and Dependency Injection in Java? (reply)
  • 5 Books to be taught Object-Oriented Design Patterns in Java? (books)

Thanks for studying this tutorial, if you happen to like this content material then please share it with your folks and colleagues. When you’ve got any suggestions or suggestion then please drop a remark. If you happen to simply wish to do one factor at this second then go and browse “Head First Design Sample”

P. S. – If you’re eager to be taught Design patterns in Java however
searching for a free on-line coaching course to start out with then you may
additionally take a look at these Java design sample programs for knowledgeable builders. It accommodates my favourite programs to be taught design patterns in depth. 



RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments