Strategy can be either interface or abstract class. This pattern helps to hide the implementation details from the method callers, and it's just a simple illustration of interface-oriented programming.
This pattern is quite similar to the Strategy Pattern except that here the strategy details are hidden from the proxy dependents, however in Strategy Pattern the concrete strategy is injected through the constructor.
Note both StrategyProxy and ConcreteStrategy have implement the Strategy interface.
Note only BeggerAdaptor has implemented the Worker interface.
Factory Patterns
Singleton Pattern
There are multiple implementation methods for Singleton Pattern in Java as listed here - Java Singleton Design Pattern Best Practices with Examples. My favorite one is Bill Pugh Singleton Implementation, because it's concise and thread-safe.
OperationAdd and OperationMinus classes implement Operation interface.
Note that from my perspective of view Factory Pattern and Abstract Factory Pattern don't provide much value to simplify the program or make the logic clearer, so that I would prefer not to introduce them here.
Flyweight Pattern
This pattern is to reduce the cost of resource on recreating instances, one common example is Java String.
In Java the strings with the same value are actually refering to the same underlying object. Although the resource used by creating a string is not substantial, because the number of operations is large, it still impact tremendously on the program overall.
Note that in Simple Factory Pattern a new object is always returned, however in FlyWeight Pattern, only when there is no such instance will a new object be created and returned.
Here we set the options for the builder and finally it will create the instance based on the requirement.
Prototype Pattern
It's just to implement the Cloneable interface in java. Note that if you want to create a immutable class, you should follow How to create Immutable class in Java? and use deep copy instead of shallow copy.
publicinterfaceState {voidhandle(Context context);}classStateStartedimplementsState { @Overridepublicvoidhandle(Context context) {// business logic herecontext.state=newStateB(); }}classStateBimplementsState { @Overridepublicvoidhandle(Context context) {// business logic herecontext.state=newStateFinished(); }}classStateFinishedimplementsState { @Overridepublicvoidhandle(Context context) {// business logic hereSystem.out.println("finished"); }}classContext {privateState state; publicContext() {this.state=newStateStarted(); }publicStategetState() {returnthis.state; }publicvoidrequest() {this.state().handle(this); // go to next state }}publicstaticvoidmain(String[] args) {Context context =newContext();context.request();context.request();context.request();}
In this way the business logic for different states is implemented in the related State, and the correlation between different business units is reduced.
Here the concrete Expression classes will interpret the context accordingly. This pattern can be used in syntax tree (I don't quite understand this, anyone can give an illustration?).
publicinterfaceVisitor {voidvisit(Element e);}publicinterfaceElement {voidaccept(Visitor v);}publicclassConcreteVisitorimplementsVisitor { @Overridepublicvoidvisit(Element e) {// TODO: }}publicclassConcreteElementimplementsElement { @Overridepublicvoidaccept(Visitor v) {v.visit(this); }}classEntiretyimplementsElement {privateList<Element> elements =newArrayList<>();publicvoidadd(Element e) {elements.add(e); }publicvoidremove(Element e) {elements.remove(e); } @Overridepublicvoidaccept(Visitor v) {for (Element e :this.elements) {e.accept(v); } }}publicstaticvoidmain(String[] args) {Visitor v =newConcreteVisitor();Entirety e =newEntirety();e.add(newConcreteElement());e.accept(v);}
This pattern encapsulates the elements inside an Entirety object and allows the Visitor instances to visit it's internal elements.
Others
Template Pattern
abstractclassAbstractClass {publicvoid templateMethod {System.out.println("I am the stupid template..."); }}# or use interfacein Java 8 or abovepublicinterfaceTemplate {defaultvoidtemplateMethod() {System.out.println("I am the stupid template..."); }}
The target for this pattern is DRY - Don't Repeat Yourself.
This pattern is quite common in frontend application when preparing the data to be submitted to the backend.
classData {privateString username;privateint amount;publicData(String username,int amount) {this.username= username;this.amount= amount; }publicStringgetUsername() {returnthis.username; }publicsetUsername(String username) {this.username= username; }publicintgetAmount() {returnthis.amount; }publicsetAmount(int amount) {this.amount= amount; }publicDatacreateMemo() {returnnewData(this.username,this.amount); }}publicstaticvoidmain(String[] args) {Data data =newData("Alice",15);Data memo =data.createMemo();data.setUsername("Bob");if (submit(data)==false) {// revert the data to the original statedata.setUsername(memo.getUsername());// or we can just replace the object with the memo which // depends on the context }}
Composite Pattern
Composite Pattern combines objects into a tree structure to represent the "part-whole" hierarchy.
publicinterfaceComponent {voidadd(Component c);voidremove(Component c);voiddisplay(int depth);}classLeafimplementsComponent {privateString name;publicLeaf(String name) {this.name= name; } @Overridepublicvoidadd(Component c) {// do nothing since it's a leaf node } @Overridepublicvoidremove(Component c) {// do nothing since it's a leaf node } @Overridepublicvoiddisplay(int depth) {System.out.println(newString(newchar[depth]).replace("\0","-") +" "+ name); }}classCompositeimplementsComponent {privateList<Component> list =newArrayList<>();privateString name;publicComposite(String name) {this.name= name; } @Overridepublicvoidadd(Component c) {list.add(c); } @Overridepublicvoidremove(Component c) {list.remove(c); } @Overridepublicvoiddisplay(int depth) {System.out.println(newString(newchar[depth]).replace("\0","-") +" "+ name);for (Component c : list) {c.display(depth); } }}publicstaticvoidmain(String[] args) {Composite root =newComposite("root");root.add(newLeaf("Left"));root.add(newLeaf("Right"));root.display(1);}
Actually it's a preorder tree traversal which can be implemented as
In Java there are Iterator<T> interface and Iterable<T> interface. The Iterable<T> requires an implementation of Iterator<T> iterator(); to return an Iterator<T> object. The Iterator<T> requires the implementation of boolean hasNext(); and T next(); methods.
Here the implementation is one to one, obviously the business case might be many-to-many, and then the logic wrapped inside the mediator would be more complicated.
Principles
SRP
Single Responsibility Principle.
Open-Close Principle
Open to extension
Closed to modification
Dependency Inversion Principle
Interface-oriented programming.
LoD Principle
The Law of Demeter (LoD) or principle of least knowledge is a design guideline for developing software, particularly object-oriented programs.