Structural models of design patterns

The bridge model

Avoid class inheritance whenever possible and use composition/aggregation whenever possible

Description: The high dependency of inherited method subclasses and superclasses limits reuse and program flexibility.



Select different interfaces to implement different types of services

import org.junit.Test;
public classThe bridge model{
       @Test
       public void test(a)
       {
             ColocalateFactory a=new BlackFactory();
             a.ColocalateMarking();
             ColocalateFactory b=newWhilteFactory(); b.ColocalateMarking(); }}interface ColocalateFactory
{
void ColocalateMarking(a);  
}
class BlackFactory implements ColocalateFactory
{
       @Override
       public void ColocalateMarking(a) {
             // TODO Auto-generated method stub
             System.out.println("Producing dark chocolate."); }}class WhilteFactory implements ColocalateFactory
{
       @Override
       public void ColocalateMarking(a) {
             // TODO Auto-generated method stub
             System.out.println("Producing white chocolate"); }}Copy the code

Adapter pattern description: Maintenance personnel handle the same or similar functionality, but in different ways. Make a unified call to the interface.

  • When injecting classes that need to be adapted, use the set method instead of new to instantiate objects to prevent hardening.
  • The method of the adaptor class is not parallel to the method of the adaptor class, but is called.
public interface Charger {
       void GetPower(a);
}
// Charger A
public class ChargerA implements Charger {
       @Override
       public void GetPower(a) {
             // TODO Auto-generated method stub
             System.out.println("Use 220V after charging"); }}// Charger B
public class ChargerB implements Charger {
       @Override
       public void GetPower(a) {
             // TODO Auto-generated method stub
             System.out.println("Charge with 200V"); }}// Universal charger
import org.junit.Test;
public class MultCharger implements Charger {
       
       private Charger charger;
       
       public void setCharger(Charger charger) {
             this.charger = charger;
       }
       @Override
       public void GetPower(a) {
             // TODO Auto-generated method stub
             this.charger.GetPower();
       }
       
       @Test
       public void test(a)
       {
             Charger a=new ChargerA();
             Charger b=new ChargerB();
             
             MultCharger Multcharger=newMultCharger(); Multcharger.setCharger(a); Multcharger.GetPower(); Multcharger.setCharger(b); Multcharger.GetPower(); }}Copy the code

The decorator pattern describes how to dynamically extend the functionality of an object without changing the existing class file or using inheritance. (This determines that class methods cannot be added directly.)

  • Adapter pattern adaptor objects and adaptor objects may not have a relationship that implements a uniform interface (that is, sibling classes). The goal: compatibility
  • Decorator pattern: Is an alternative to inheritance and is more flexible. The purpose: to enhance
import org.junit.Test;
public classDecorator mode{
       
       @Test
       public void test(a)
       {
             Soldier s=new SmallSoldier();
             BigSoldier b=newBigSoldier(); b.setSoldier(s); b.fighting(); }}interface Soldier
{
       void fighting(a);
}
class SmallSoldier implements Soldier
{
       @Override
       public void fighting(a) {
             // TODO Auto-generated method stub
             System.out.println("Ordinary soldiers are fighting."); }}class BigSoldier implements Soldier
{
       
       private Soldier soldier;
       
       public void setSoldier(Soldier soldier) {
             this.soldier = soldier;
       }
       @Override
       public void fighting(a) {
             // TODO Auto-generated method stub
             soldier.fighting();
             System.out.println("We've got long-range soldiers on standby."); }}Copy the code

The composition pattern uses the recursive idea of combining objects into a tree structure to represent a “partial-whole” complement to the hierarchy, and provides three methods for adding children, removing children, and displaying the structure. Application scenario: Tree-structured data operations, such as file directory display and multi-level directory display. Method: Implement by inheriting abstract classes

public abstract class Node {
            protected String name;/ / name
            
            // Constructor assignment
             public Node(String name){
                 this.name = name;
             }
            // New node: file node does not have this method, directory node overrides this method
            public void addNode(Node node) throws Exception{
                throw new Exception("Invalid exception");
            }
           
            // Delete a node
            public void removeNode(Node node)throws Exception{
                throw new Exception("Invalid exception");
            }
            // Display node: files and directories implement this method
            abstract void display(a);
}

// File node
public class Filer extends Node {
       public Filer(String name) {
             super(name);
             // TODO Auto-generated constructor stub
       }
       
       
       @Override
       void display(a) {
             // TODO Auto-generated method stubSystem.out.println(name); }}// Directory node
public class Noder extends Node{
       // Internal node list (including files and subdirectories)
       List<Node> nodeList = new ArrayList<Node>();
       public Noder(String name) {
             super(name);
             // TODO Auto-generated constructor stub
       }
       // Add a node
       public void addNode(Node node) throws Exception{
             nodeList.add(node);
       }
       // Delete a node
       public void removeNode(Node node)throws Exception
       {
             nodeList.remove(node);
       }
    // Prints the name recursively down
       @Override
       void display(a) {
             System.out.println(name);
             for(Node node:nodeList){ node.display(); }}}/ / test class
import java.io.File;
public class Clienter {
          public static void createTree(Node node) throws Exception{
                         File file = new File(node.name);
                         File[] f = file.listFiles();
                        for(File fi : f){
                              // check whether the node is a file
                            if(fi.isFile()){ 
                                // Use the absolute path to name the node
                                 Filer filer = new Filer(fi.getAbsolutePath());
                                 node.addNode(filer);
                            }
                            // Check whether the node is a directory
                            if(fi.isDirectory()){
                             // Use the absolute path to name the node
                                Noder noder = new Noder(fi.getAbsolutePath());
                                node.addNode(noder);
                                createTree(noder);// Use a recursive spanning tree structure}}}public static void main(String[] args) {
                        Node noder = new Noder("G://WeGame");
                       try {
                            createTree(noder);
                       } catch(Exception e) { e.printStackTrace(); } noder.display(); }}Copy the code

Share pattern description: Use a class to store shared resources, running sharing technology effectively supports the reuse of a large number of fine-grained objects: through the Map collection store (HashMap) provides methods to add PUT, get

public class Student {
       private String name;
       private int  age;
       
       public Student(String name,int age)
       {
             this.name=name;
             this.age=age;
             
       }
       public String getName(a) {
             return name;
       }
       public void setName(String name) {
             this.name = name;
       }
       public int getAge(a) {
             return age;
       }
       public void setAge(int age) {
             this.age = age;
       }
       @Override
       public String toString(a) {
             return "Student [name=" + name + ", age=" + age + "]"; }}import java.util.HashMap;
import org.junit.Test;
public class StudentFactory {
       static HashMap <String,Student>map=new HashMap<>();
       
       public static Student getStudent(String name)
       {
             
             if(map.get(name)! =null)
             {
                    return map.get(name);
             }
             return null;
             
       }
       
       public static void addStudent(Student s)
       {
             map.put(s.getName(), s);
       }
       
       public static void display(a)
       {
             System.out.println(map.entrySet());
       }
       
       @Test
       public void test001(a)
       {
       StudentFactory.addStudent(new Student("luo".18));   
       StudentFactory.addStudent(new Student("li".17));    
    Student s=      StudentFactory.getStudent("luo"); System.out.println(s); StudentFactory.display(); }}Copy the code

The facade pattern does not change the content of the old class, but reorganizes the business through a facade class pair of associated methods. General use between subsystem and access, for access to shield complex subsystem call, using fresh and new appearance class to provide a simple call method, specific implementation by the appearance class to subsystem call. (Business logic integration)

import org.junit.Test;
public classThe appearance model{
       private FactoryA a=new FactoryA();
       private FactoryB b=new FactoryB();
       public void lookplay(a)
       {
             a.funcA();
             b.funcB();
       }
       
       
       @Test
       public void test(a)
       {
             newLook mode ().lookplay(); }}class FactoryA
{
       public void funcA(a)
       {
             System.out.println("Tell someone you love them."); }}class FactoryB
{
       public void funcB(a)
       {
             System.out.println("Say yes to someone's love."); }}Copy the code

Proxy mode description: Provides a proxy for third-party objects to control their access (third-party wall scaling behavior) note: Adapters are one-to-many and proxies are one-to-one.

public interface FactoryInterface {
       void Breakmaking(a);
}

public class Factory implements FactoryInterface{
       @Override
       public void Breakmaking(a) {
             // TODO Auto-generated method stub
             System.out.println("Making bread."); }}import org.junit.Test;
public class AgentFactory implements FactoryInterface{
       FactoryInterface f =new Factory();
       @Override
       public void Breakmaking(a) {
             // TODO Auto-generated method stub
             f.Breakmaking();
       }
       
       @Test
       public void test(a)
       {
             newAgentFactory().Breakmaking(); }}Copy the code