softwaredesignpattern
                Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| softwaredesignpattern [2014/06/19 12:04] – [Design] admin | softwaredesignpattern [2022/10/29 16:15] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | Refer: http:// | ||
| + | ====== Software Design Pattern ====== | ||
| + | **Design patterns** represent the best practices **used by experienced object-oriented software developers**. Design patterns are **solutions to general problems that software developers faced during software development**. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time. | ||
| + | **Types of Desing Pattern**: | ||
| + | ^S.N.^Name^Pattern & Description^ | ||
| + | |1|**Creational Patterns**|These design patterns provides **way to create objects while hiding the creation logic**, rather than instantiating objects directly using new opreator. This gives program more flexibility in deciding which objects need to be created for a given use case.| | ||
| + | |2|**Structural Patterns**|These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and **define ways to compose objects to obtain new functionalities**.| | ||
| + | |3|**Behavioral Patterns**|These design patterns are specifically **concerned with communication between objects**.| | ||
| + | |4|**J2EE Patterns**|These design patterns are specifically **concerned with the presentation tier**. These patterns are identified by Sun Java Center.| | ||
| + | ===== Creational Pattern: Factory Pattern ===== | ||
| + | Factory pattern is one of most used design pattern in Java. This type of design pattern comes under creational pattern as **this pattern provides one of the best ways to create an object**. | ||
| + | ==== Design ==== | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create an interface **Shape.java**:< | ||
| + | public interface Shape { | ||
| + | void draw(); | ||
| + | } | ||
| + | </ | ||
| + | - Step 2: Create **concrete classes** implementing the same interface. | ||
| + |     * Rectangle.java< | ||
| + | public class Rectangle implements Shape { | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * Square.java< | ||
| + | public class Square implements Shape { | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * Circle.java< | ||
| + | public class Circle implements Shape { | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Create a Factory to generate object of concrete class based on given information **ShapeFactory.java**< | ||
| + | public class ShapeFactory { | ||
| + | |||
| + | //use getShape method to get object of type shape | ||
| + |     | ||
| + | if(shapeType == null){ | ||
| + |           | ||
| + | } | ||
| + |       if(shapeType.equalsIgnoreCase(" | ||
| + |           | ||
| + |       } else if(shapeType.equalsIgnoreCase(" | ||
| + |           | ||
| + |       } else if(shapeType.equalsIgnoreCase(" | ||
| + |           | ||
| + | } | ||
| + | return null; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Use the Factory to get object of concrete class by passing an information such as type FactoryPatternDemo.java:< | ||
| + | public class FactoryPatternDemo { | ||
| + | |||
| + |     | ||
| + |       ShapeFactory shapeFactory = new ShapeFactory(); | ||
| + | |||
| + | //get an object of Circle and call its draw method. | ||
| + |       Shape shape1 = shapeFactory.getShape(" | ||
| + | |||
| + | //call draw method of Circle | ||
| + |       shape1.draw(); | ||
| + | |||
| + | //get an object of Rectangle and call its draw method. | ||
| + |       Shape shape2 = shapeFactory.getShape(" | ||
| + | |||
| + | //call draw method of Rectangle | ||
| + |       shape2.draw(); | ||
| + | |||
| + | //get an object of Square and call its draw method. | ||
| + |       Shape shape3 = shapeFactory.getShape(" | ||
| + | |||
| + | //call draw method of circle | ||
| + |       shape3.draw(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Verify the output.< | ||
| + | Inside Circle:: | ||
| + | Inside Rectangle:: | ||
| + | Inside Square:: | ||
| + | </ | ||
| + | ===== creational pattern: Singleton Pattern ===== | ||
| + | This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class.Ensure a class has only one instance, and provide a global point of access to it | ||
| + | ==== Design ==== | ||
| + | We're going to **create a SingleObject class**. SingleObject class have its constructor as private and **have a static instance of itself**. | ||
| + | |||
| + | SingleObject class provides a static method to get its static instance to outside world. SingletonPatternDemo, | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create a Singleton Class SingleObject.java< | ||
| + | public class SingleObject { | ||
| + | |||
| + |    // | ||
| + |     | ||
| + | |||
| + |    // | ||
| + |    // | ||
| + |     | ||
| + | |||
| + | //Get the only object available | ||
| + |     | ||
| + | return instance; | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Get the only object from the singleton class SingletonPatternDemo.java< | ||
| + | public class SingletonPatternDemo { | ||
| + |     | ||
| + | |||
| + | //illegal construct | ||
| + | //Compile Time Error: The constructor SingleObject() is not visible | ||
| + |       // | ||
| + | |||
| + | //Get the only object available | ||
| + |       SingleObject object = SingleObject.getInstance(); | ||
| + | |||
| + | //show the message | ||
| + |       object.showMessage(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Verify the output< | ||
| + | Hello World! | ||
| + | </ | ||
| + | ===== Structural Pattern: Adapter Pattern ===== | ||
| + | Adapter pattern works as **a bridge between two incompatible interfaces**. This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces. | ||
| + | ==== Design ==== | ||
| + | We've an interface **MediaPlayer interface** and a concrete class AudioPlayer implementing the MediaPlayer interface. AudioPlayer can **play mp3 format** audio files by default. | ||
| + | |||
| + | We're having another interface **AdvancedMediaPlayer interface** and concrete classes implementing the AdvancedMediaPlayer interface.These classes can **play vlc and mp4 format** files. | ||
| + | |||
| + | We want to **make AudioPlayer to play other formats as well**. To attain this, we've **created an adapter class MediaAdapter** which implements the MediaPlayer interface and uses AdvancedMediaPlayer objects to play the required format.\\ | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: **Create interfaces** for Media Player and Advanced Media Player  | ||
| + |     * MediaPlayer.java< | ||
| + | public interface MediaPlayer { | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + |     * AdvancedMediaPlayer.java< | ||
| + | public interface AdvancedMediaPlayer { | ||
| + |     | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + | - Step 2: Create **concrete classes** implementing the AdvancedMediaPlayer interface | ||
| + |     * VlcPlayer.java< | ||
| + | public class VlcPlayer implements AdvancedMediaPlayer{ | ||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + | //do nothing | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * Mp4Player.java< | ||
| + | public class Mp4Player implements AdvancedMediaPlayer{ | ||
| + | |||
| + |     | ||
| + |     | ||
| + | //do nothing | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Create **adapter class** implementing the MediaPlayer interface MediaAdapter.java< | ||
| + | public class MediaAdapter implements MediaPlayer { | ||
| + | |||
| + |     | ||
| + | |||
| + |     | ||
| + |       if(audioType.equalsIgnoreCase(" | ||
| + |           | ||
| + |       } else if (audioType.equalsIgnoreCase(" | ||
| + |           | ||
| + | } | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       if(audioType.equalsIgnoreCase(" | ||
| + |           | ||
| + |       }else if(audioType.equalsIgnoreCase(" | ||
| + |           | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Create **concrete class implementing the MediaPlayer interface** AudioPlayer.java< | ||
| + | public class AudioPlayer implements MediaPlayer { | ||
| + |     | ||
| + | |||
| + |     | ||
| + |     | ||
| + | |||
| + | //inbuilt support to play mp3 music files | ||
| + |       if(audioType.equalsIgnoreCase(" | ||
| + |           | ||
| + | } | ||
| + |       // | ||
| + |       else if(audioType.equalsIgnoreCase(" | ||
| + |          || audioType.equalsIgnoreCase(" | ||
| + |           | ||
| + |           | ||
| + | } | ||
| + | else{ | ||
| + |           | ||
| + |             audioType + " format not supported" | ||
| + | } | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Use the AudioPlayer to **play different types of audio formats** AdapterPatternDemo.java< | ||
| + | public class AdapterPatternDemo { | ||
| + |     | ||
| + |       AudioPlayer audioPlayer = new AudioPlayer(); | ||
| + | |||
| + |       audioPlayer.play(" | ||
| + |       audioPlayer.play(" | ||
| + |       audioPlayer.play(" | ||
| + |       audioPlayer.play(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 6: Verify the output< | ||
| + | Playing mp3 file. Name: beyond the horizon.mp3 | ||
| + | Playing mp4 file. Name: alone.mp4 | ||
| + | Playing vlc file. Name: far far away.vlc | ||
| + | Invalid media. avi format not supported | ||
| + | </ | ||
| + | ===== Structural Pattern: Composite Pattern ===== | ||
| + | Composite pattern is used where we need to treat a group of objects in similar way as a single object.  | ||
| + | ==== Design ==== | ||
| + | We've a **class Employee** which **acts as composite pattern actor class**. CompositePatternDemo, | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create Employee class having list of Employee objects Employee.java< | ||
| + | import java.util.ArrayList; | ||
| + | import java.util.List; | ||
| + | |||
| + | public class Employee { | ||
| + |     | ||
| + |     | ||
| + |     | ||
| + |     | ||
| + | |||
| + | // constructor | ||
| + |     | ||
| + | this.name = name; | ||
| + | this.dept = dept; | ||
| + | this.salary = sal; | ||
| + |       subordinates = new ArrayList< | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       subordinates.add(e); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       subordinates.remove(e); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       return (" | ||
| + | +", dept : "+ dept + ", salary :" | ||
| + |       + salary+" | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Use the Employee class to create and print employee hierarchy CompositePatternDemo.java< | ||
| + | public class CompositePatternDemo { | ||
| + |     | ||
| + |       Employee CEO = new Employee(" | ||
| + | |||
| + |       Employee headSales = new Employee(" | ||
| + | |||
| + |       Employee headMarketing = new Employee(" | ||
| + | |||
| + |       Employee clerk1 = new Employee(" | ||
| + |       Employee clerk2 = new Employee(" | ||
| + | |||
| + |       Employee salesExecutive1 = new Employee(" | ||
| + |       Employee salesExecutive2 = new Employee(" | ||
| + | |||
| + |       CEO.add(headSales); | ||
| + |       CEO.add(headMarketing); | ||
| + | |||
| + |       headSales.add(salesExecutive1); | ||
| + |       headSales.add(salesExecutive2); | ||
| + | |||
| + |       headMarketing.add(clerk1); | ||
| + |       headMarketing.add(clerk2); | ||
| + | |||
| + | //print all employees of the organization | ||
| + |       System.out.println(CEO);  | ||
| + | for (Employee headEmployee : CEO.getSubordinates()) { | ||
| + |           | ||
| + | for (Employee employee : headEmployee.getSubordinates()) { | ||
| + |             System.out.println(employee); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Verify the output< | ||
| + | Employee :[ Name : John, dept : CEO, salary :30000 ] | ||
| + | Employee :[ Name : Robert, dept : Head Sales, salary :20000 ] | ||
| + | Employee :[ Name : Richard, dept : Sales, salary :10000 ] | ||
| + | Employee :[ Name : Rob, dept : Sales, salary :10000 ] | ||
| + | Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ] | ||
| + | Employee :[ Name : Laura, dept : Marketing, salary :10000 ] | ||
| + | Employee :[ Name : Bob, dept : Marketing, salary :10000 ] | ||
| + | </ | ||
| + | ===== Structural Pattern: Decorator pattern ===== | ||
| + | Decorator pattern allows to **add new functionality an existing object without altering its structure**. This type of design pattern comes under structural pattern as this pattern **acts as a wrapper to existing class**. | ||
| + | ==== Design ==== | ||
| + | Below are demonstrating use of Decorator pattern via following example in which we'll **decorate a shape** with **some color without alter shape class**. | ||
| + | |||
| + | We're going to create a **Shape interface** and concrete classes implementing the Shape interface. We then create a abstract decorator **class ShapeDecorator implementing the Shape interface** and having Shape object as its instance variable. | ||
| + | |||
| + | **RedShapeDecorator** is concrete class **implementing ShapeDecorator**. | ||
| + | |||
| + | DecoratorPatternDemo, | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create an **interface Shape.java**< | ||
| + | public interface Shape { | ||
| + | void draw(); | ||
| + | } | ||
| + | </ | ||
| + | - Step 2: Create concrete classes implementing the same interface: | ||
| + |     * Rectangle.java< | ||
| + | public class Rectangle implements Shape { | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * Circle.java< | ||
| + | public class Circle implements Shape { | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Create **abstract decorator class** implementing the Shape interface **ShapeDecorator.java**< | ||
| + | public abstract class ShapeDecorator implements Shape { | ||
| + |     | ||
| + | |||
| + |     | ||
| + |       this.decoratedShape = decoratedShape; | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       decoratedShape.draw(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Create concrete decorator class **extending the ShapeDecorator class RedShapeDecorator.java**< | ||
| + | public class RedShapeDecorator extends ShapeDecorator { | ||
| + | |||
| + |     | ||
| + |       super(decoratedShape); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       decoratedShape.draw(); | ||
| + |       setRedBorder(decoratedShape); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Use the **RedShapeDecorator** to **decorate Shape objects** DecoratorPatternDemo.java< | ||
| + | public class DecoratorPatternDemo { | ||
| + |     | ||
| + | |||
| + | Shape circle = new Circle(); | ||
| + | |||
| + | Shape redCircle = new RedShapeDecorator(new Circle()); | ||
| + | |||
| + |       Shape redRectangle = new RedShapeDecorator(new Rectangle()); | ||
| + |       System.out.println(" | ||
| + |       circle.draw(); | ||
| + | |||
| + |       System.out.println(" | ||
| + |       redCircle.draw(); | ||
| + | |||
| + |       System.out.println(" | ||
| + |       redRectangle.draw(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 6: Verify the output< | ||
| + | Circle with normal border | ||
| + | Shape: Circle | ||
| + | |||
| + | Circle of red border | ||
| + | Shape: Circle | ||
| + | Border Color: Red | ||
| + | |||
| + | Rectangle of red border | ||
| + | Shape: Rectangle | ||
| + | Border Color: Red | ||
| + | </ | ||
| + | ===== Behavior Pattern: Iterator Pattern ===== | ||
| + | Iterator pattern is very commonly used design pattern in Java and .Net programming environment. This pattern is used to **get a way to access the elements of a collection object** in sequential manner **without any need to know its underlying representation**. | ||
| + | ==== Design ==== | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + | - Step 1: Create interfaces: | ||
| + |     * Iterator.java< | ||
| + | public interface Iterator { | ||
| + |     | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + |     * Container.java< | ||
| + | public interface Container { | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Create concrete class implementing the Container interface. This class has inner class NameIterator implementing the Iterator interface NameRepository.java< | ||
| + | public class NameRepository implements Container { | ||
| + |     | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       return new NameIterator(); | ||
| + | } | ||
| + | |||
| + |     | ||
| + | |||
| + | int index; | ||
| + | |||
| + | @Override | ||
| + | public boolean hasNext() { | ||
| + |           | ||
| + | return true; | ||
| + | } | ||
| + |           | ||
| + | } | ||
| + | |||
| + | @Override | ||
| + | public Object next() { | ||
| + |           | ||
| + |             return names[index++]; | ||
| + | } | ||
| + |           | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Use the NameRepository to get iterator and print names IteratorPatternDemo.java< | ||
| + | public class IteratorPatternDemo { | ||
| + | |||
| + |     | ||
| + |       NameRepository namesRepository = new NameRepository(); | ||
| + | |||
| + |       for(Iterator iter = namesRepository.getIterator(); | ||
| + |           | ||
| + |           | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Verify the output< | ||
| + | Name : Robert | ||
| + | Name : John | ||
| + | Name : Julie | ||
| + | Name : Lora | ||
| + | </ | ||
| + | ===== Behavior Pattern: Observer Pattern ===== | ||
| + | Observer pattern is used when there is one to many relationship between objects such as **if one object is modified, its depenedent objects are to be notified automatically**. Observer pattern falls under behavioral pattern category. | ||
| + | ==== Design ==== | ||
| + | Observer pattern uses three actor classes. **Subject, Observer and Client**. **Subject, an object having methods to attach and de-attach observers to a client object**. We've created classes Subject, Observer abstract class and concrete classes extending the abstract class the Observer. | ||
| + | |||
| + | ObserverPatternDemo, | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create **Subject class** Subject.java:< | ||
| + | import java.util.ArrayList; | ||
| + | import java.util.List; | ||
| + | |||
| + | public class Subject { | ||
| + | |||
| + |     | ||
| + |       = new ArrayList< | ||
| + |     | ||
| + | |||
| + |     | ||
| + | return state; | ||
| + | } | ||
| + | |||
| + |     | ||
| + | this.state = state; | ||
| + |       notifyAllObservers(); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       observers.add(observer); | ||
| + | } | ||
| + | |||
| + |     | ||
| + | for (Observer observer : observers) { | ||
| + |           | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Create Observer class Observer.java< | ||
| + | public abstract class Observer { | ||
| + |     | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + | - Step 3: Create concrete observer classes: | ||
| + |     * BinaryObserver.java< | ||
| + | public class BinaryObserver extends Observer{ | ||
| + | |||
| + |     | ||
| + | this.subject = subject; | ||
| + |       this.subject.attach(this); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println( " | ||
| + | + Integer.toBinaryString( subject.getState() ) ); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * OctalObserver.java< | ||
| + | public class OctalObserver extends Observer{ | ||
| + | |||
| + |     | ||
| + | this.subject = subject; | ||
| + |       this.subject.attach(this); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       | ||
| + | + Integer.toOctalString( subject.getState() ) ); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * HexaObserver.java< | ||
| + | public class HexaObserver extends Observer{ | ||
| + | |||
| + |     | ||
| + | this.subject = subject; | ||
| + |       this.subject.attach(this); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |     | ||
| + |       System.out.println( "Hex String: "  | ||
| + | + Integer.toHexString( subject.getState() ).toUpperCase() ); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Use Subject and concrete observer objects ObserverPatternDemo.java< | ||
| + | public class ObserverPatternDemo { | ||
| + |     | ||
| + | Subject subject = new Subject(); | ||
| + | |||
| + |       new HexaObserver(subject); | ||
| + |       new OctalObserver(subject); | ||
| + |       new BinaryObserver(subject); | ||
| + | |||
| + |       System.out.println(" | ||
| + |       subject.setState(15); | ||
| + |       System.out.println(" | ||
| + |       subject.setState(10); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Verify the output< | ||
| + | First state change: 15 | ||
| + | Hex String: F | ||
| + | Octal String: 17 | ||
| + | Binary String: 1111 | ||
| + | Second state change: 10 | ||
| + | Hex String: A | ||
| + | Octal String: 12 | ||
| + | Binary String: 1010 | ||
| + | </ | ||
| + | ===== Behavior Pattern: | ||
| + | In State pattern a **class behavior changes based on its state**. This type of design pattern comes under behavior pattern. | ||
| + | ==== Design ==== | ||
| + | We're going to create a **State interface defining a action** and **concrete state classes implementing the State interface**. Context is a class which carries a State. | ||
| + | |||
| + | StatePatternDemo, | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create an interface Image.java< | ||
| + | public interface State { | ||
| + |     | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Create concrete classes implementing the same interface  | ||
| + |     * StartState.java< | ||
| + | public class StartState implements State { | ||
| + | |||
| + |     | ||
| + |       System.out.println(" | ||
| + |       context.setState(this); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       return "Start State"; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * StopState.java< | ||
| + | public class StopState implements State { | ||
| + | |||
| + |     | ||
| + |       System.out.println(" | ||
| + |       context.setState(this); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       return "Stop State"; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Create Context Class Context.java< | ||
| + | public class Context { | ||
| + |     | ||
| + | |||
| + |     | ||
| + | state = null; | ||
| + | } | ||
| + | |||
| + |     | ||
| + | this.state = state; | ||
| + | } | ||
| + | |||
| + |     | ||
| + | return state; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Use the Context to see change in behaviour when State changes StatePatternDemo.java< | ||
| + | public class StatePatternDemo { | ||
| + |     | ||
| + | Context context = new Context(); | ||
| + | |||
| + |       StartState startState = new StartState(); | ||
| + |       startState.doAction(context); | ||
| + | |||
| + |       System.out.println(context.getState().toString()); | ||
| + | |||
| + |       StopState stopState = new StopState(); | ||
| + |       stopState.doAction(context); | ||
| + | |||
| + |       System.out.println(context.getState().toString()); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Verify the output< | ||
| + | Player is in start state | ||
| + | Start State | ||
| + | Player is in stop state | ||
| + | Stop State | ||
| + | </ | ||
| + | ===== Model-View-Controller Pattern ===== | ||
| + | This pattern is used to separate application' | ||
| + | * Model - Model **represents an object** or JAVA POJO carrying data. It can **also have logic to update controller if its data changes**. | ||
| + | * View - View **represents the visualization of the data** that model contains. | ||
| + | * Controller - Controller acts on both Model and view. It **controls the data flow into model object** and **updates the view whenever data changes**. It keeps **View and Model separate**. | ||
| + | ==== Design ==== | ||
| + | We're going to create a **Student object** acting as a model. **StudentView** will be a view class which can print student details on console and **StudentController** is the controller class responsible to store data in Student object and update view StudentView accordingly. | ||
| + | |||
| + | **MVCPatternDemo**, | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create Model Student.java< | ||
| + | public class Student { | ||
| + |     | ||
| + |     | ||
| + |     | ||
| + | return rollNo; | ||
| + | } | ||
| + |     | ||
| + | this.rollNo = rollNo; | ||
| + | } | ||
| + |     | ||
| + | return name; | ||
| + | } | ||
| + |     | ||
| + | this.name = name; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Create View StudentView.java< | ||
| + | public class StudentView { | ||
| + |     | ||
| + |       System.out.println(" | ||
| + |       System.out.println(" | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Create Controller StudentController.java< | ||
| + | public class StudentController { | ||
| + |     | ||
| + |     | ||
| + | |||
| + |     | ||
| + | this.model = model; | ||
| + | this.view = view; | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       model.setName(name); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       return model.getName(); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       model.setRollNo(rollNo); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       return model.getRollNo(); | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       view.printStudentDetails(model.getName(), | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Use the StudentController methods to demonstrate MVC design pattern usage MVCPatternDemo.java< | ||
| + | public class MVCPatternDemo { | ||
| + |     | ||
| + | |||
| + | //fetch student record based on his roll no from the database | ||
| + |       Student model  = retriveStudentFromDatabase(); | ||
| + | |||
| + | //Create a view : to write student details on console | ||
| + |       StudentView view = new StudentView(); | ||
| + | |||
| + |       StudentController controller = new StudentController(model, | ||
| + | |||
| + |       controller.updateView(); | ||
| + | |||
| + | //update model data | ||
| + |       controller.setStudentName(" | ||
| + | |||
| + |       controller.updateView(); | ||
| + | } | ||
| + | |||
| + |     | ||
| + | Student student = new Student(); | ||
| + |       student.setName(" | ||
| + |       student.setRollNo(" | ||
| + | return student; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Verify the output< | ||
| + | Student:  | ||
| + | Name: Robert | ||
| + | Roll No: 10 | ||
| + | Student:  | ||
| + | Name: John | ||
| + | Roll No: 10 | ||
| + | </ | ||
| + | ===== Behavior Pattern: | ||
| + | ==== Design ==== | ||
| + | We've created an **interface Order** which is **acting as a command**. We've created a **Stock class** which acts **as a request**. We've concrete command classes **BuyStock and SellStock implementing Order interface** which will do **actual command processing**. A class **Broker** is created which acts **as a invoker object**. It can take order and place orders. | ||
| + | |||
| + | Broker object uses command pattern to identify which object will execute which command based on type of command. CommandPatternDemo, | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create a command interface Order.java< | ||
| + | public interface Order { | ||
| + | void execute(); | ||
| + | } | ||
| + | </ | ||
| + |   - Step 2: Create a request class Stock.java< | ||
| + | public class Stock { | ||
| + | |||
| + |     | ||
| + |     | ||
| + | |||
| + |     | ||
| + |       System.out.println(" | ||
| + |           | ||
| + | } | ||
| + |     | ||
| + |       System.out.println(" | ||
| + |           | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | - Step 3: Create concrete classes implementing the Order interface: | ||
| + |     * BuyStock.java< | ||
| + | public class BuyStock implements Order { | ||
| + |     | ||
| + | |||
| + |     | ||
| + | this.abcStock = abcStock; | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       abcStock.buy(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |     * SellStock.java< | ||
| + | public class SellStock implements Order { | ||
| + |     | ||
| + | |||
| + |     | ||
| + | this.abcStock = abcStock; | ||
| + | } | ||
| + | |||
| + |     | ||
| + |       abcStock.sell(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Create command invoker class Broker.java< | ||
| + | import java.util.ArrayList; | ||
| + | import java.util.List; | ||
| + | |||
| + |     | ||
| + |     | ||
| + | |||
| + |     | ||
| + |       orderList.add(order); | ||
| + | } | ||
| + | |||
| + |     | ||
| + | for (Order order : orderList) { | ||
| + |           | ||
| + | } | ||
| + |       orderList.clear(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 5: Use the Broker class to take and execute commands CommandPatternDemo.java< | ||
| + | public class CommandPatternDemo { | ||
| + |     | ||
| + | Stock abcStock = new Stock(); | ||
| + | |||
| + |       BuyStock buyStockOrder = new BuyStock(abcStock); | ||
| + |       SellStock sellStockOrder = new SellStock(abcStock); | ||
| + | |||
| + | Broker broker = new Broker(); | ||
| + |       broker.takeOrder(buyStockOrder); | ||
| + |       broker.takeOrder(sellStockOrder); | ||
| + | |||
| + |       broker.placeOrders(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 6: Verify the output< | ||
| + | Stock [ Name: ABC, Quantity: 10 ] bought | ||
| + | Stock [ Name: ABC, Quantity: 10 ] sold | ||
| + | </ | ||
| + | ===== Behavior Pattern: Template Pattern ===== | ||
| + | Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm' | ||
| + | ==== Design ==== | ||
| + | {{: | ||
| + | {{: | ||
| + | ==== Implementation ==== | ||
| + |   - Step 1: Create an abstract class with a template method being final Game.java< | ||
| + | public abstract class Game { | ||
| + |     | ||
| + |     | ||
| + |     | ||
| + | |||
| + |    // | ||
| + |     | ||
| + | |||
| + |       // | ||
| + |       initialize(); | ||
| + | |||
| + | //start game | ||
| + |       startPlay(); | ||
| + | |||
| + | //end game | ||
| + | endPlay(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | - Step 2: Create concrete classes extending the above class | ||
| + |     * Cricket.java< | ||
| + | public class Cricket extends Game { | ||
| + | |||
| + |     | ||
| + | void endPlay() { | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | |||
| + |     | ||
| + | void initialize() { | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | |||
| + |     | ||
| + | void startPlay() { | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + |     * Football.java< | ||
| + | public class Football extends Game { | ||
| + | |||
| + |     | ||
| + | void endPlay() { | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | |||
| + |     | ||
| + | void initialize() { | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | |||
| + |     | ||
| + | void startPlay() { | ||
| + |       System.out.println(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 3: Use the Game's template method play() to demonstrate a defined way of playing game TemplatePatternDemo.java< | ||
| + | public class TemplatePatternDemo { | ||
| + |     | ||
| + | |||
| + | Game game = new Cricket(); | ||
| + |       game.play(); | ||
| + |       System.out.println(); | ||
| + | game = new Football(); | ||
| + |       game.play(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + |   - Step 4: Verify the output< | ||
| + | Cricket Game Initialized! Start playing. | ||
| + | Cricket Game Started. Enjoy the game! | ||
| + | Cricket Game Finished! | ||
| + | |||
| + | Football Game Initialized! Start playing. | ||
| + | Football Game Started. Enjoy the game! | ||
| + | Football Game Finished! | ||
| + | </ | ||
