23种设计模式详解及其在Spring中的应用

创建型设计模式

  1. 工厂方法模式 (Factory Method Pattern)

    • 原理:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法使一个类的实例化延迟到其子类。
    • 代码实例
      // 产品接口
      interface Product {
          void use();
      }
      
      // 具体产品A
      class ConcreteProductA implements Product {
          public void use() {
              System.out.println("Using Product A");
          }
      }
      
      // 具体产品B
      class ConcreteProductB implements Product {
          public void use() {
              System.out.println("Using Product B");
          }
      }
      
      // 工厂基类
      abstract class Creator {
          public abstract Product factoryMethod();
          
          public void doSomething() {
              Product product = factoryMethod();
              product.use();
          }
      }
      
      // 具体工厂A
      class ConcreteCreatorA extends Creator {
          public Product factoryMethod() {
              return new ConcreteProductA();
          }
      }
      
      // 具体工厂B
      class ConcreteCreatorB extends Creator {
          public Product factoryMethod() {
              return new ConcreteProductB();
          }
      }
      
      // 客户端代码
      public class FactoryMethodExample {
          public static void main(String[] args) {
              Creator creatorA = new ConcreteCreatorA();
              creatorA.doSomething();
              
              Creator creatorB = new ConcreteCreatorB();
              creatorB.doSomething();
          }
      }
      
    • 使用场景:适用于需要延迟实例化的情况,例如根据配置文件选择不同实现类。
    • Spring应用:Spring中的BeanFactory就是工厂方法模式的应用。
  2. 抽象工厂模式 (Abstract Factory Pattern)

    • 原理:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    • 代码实例
      // 抽象产品A
      interface ProductA {
          void use();
      }
      
      // 抽象产品B
      interface ProductB {
          void eat();
      }
      
      // 具体产品A1
      class ConcreteProductA1 implements ProductA {
          public void use() {
              System.out.println("Using Product A1");
          }
      }
      
      // 具体产品B1
      class ConcreteProductB1 implements ProductB {
          public void eat() {
              System.out.println("Eating Product B1");
          }
      }
      
      // 抽象工厂
      interface AbstractFactory {
          ProductA createProductA();
          ProductB createProductB();
      }
      
      // 具体工厂1
      class ConcreteFactory1 implements AbstractFactory {
          public ProductA createProductA() {
              return new ConcreteProductA1();
          }
          
          public ProductB createProductB() {
              return new ConcreteProductB1();
          }
      }
      
      // 客户端代码
      public class AbstractFactoryExample {
          public static void main(String[] args) {
              AbstractFactory factory = new ConcreteFactory1();
              ProductA productA = factory.createProductA();
              ProductB productB = factory.createProductB();
              
              productA.use();
              productB.eat();
          }
      }
      
    • 使用场景:适用于需要创建多个相互关联的对象系列,而无需关心它们具体实现的情况。
    • Spring应用:Spring的AbstractApplicationContext可以视为抽象工厂的实现。
  3. 单例模式 (Singleton Pattern)

    • 原理:确保一个类只有一个实例,并提供一个全局访问点。
    • 代码实例
      class Singleton {
          private static Singleton instance;
          
          private Singleton() {}
          
          public static Singleton getInstance() {
              if (instance == null) {
                  synchronized (Singleton.class) {
                      if (instance == null) {
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
      }
      
      public class SingletonExample {
          public static void main(String[] args) {
              Singleton singleton1 = Singleton.getInstance();
              Singleton singleton2 = Singleton.getInstance();
              System.out.println(singleton1 == singleton2);  // 输出: true
          }
      }
      
    • 使用场景:适用于需要一个全局唯一类的情况,例如配置管理类、数据库连接池等。
    • Spring应用:Spring的@Component@Bean默认是单例模式。
  4. 建造者模式 (Builder Pattern)

    • 原理:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
    • 代码实例
      class Product {
          private String partA;
          private String partB;
          private String partC;
          
          public void setPartA(String partA) { this.partA = partA; }
          public void setPartB(String partB) { this.partB = partB; }
          public void setPartC(String partC) { this.partC = partC; }
          
          public void show() {
              System.out.println("Product parts: " + partA + ", " + partB + ", " + partC);
          }
      }
      
      class ProductBuilder {
          private Product product = new Product();
          
          public ProductBuilder buildPartA(String partA) {
              product.setPartA(partA);
              return this;
          }
          
          public ProductBuilder buildPartB(String partB) {
              product.setPartB(partB);
              return this;
          }
          
          public ProductBuilder buildPartC(String partC) {
              product.setPartC(partC);
              return this;
          }
          
          public Product build() {
              return product;
          }
      }
      
      public class BuilderPatternExample {
          public static void main(String[] args) {
              ProductBuilder builder = new ProductBuilder();
              Product product = builder.buildPartA("Part A").buildPartB("Part B").buildPartC("Part C").build();
              product.show();
          }
      }
      
    • 使用场景:构建复杂对象,且需要可变的步骤。例如构建复杂的UI。
    • Spring应用Spring BeanDefinitionBuilder用于构建Bean的定义。
  5. 原型模式 (Prototype Pattern)

    • 原理:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
    • 代码实例
      class Prototype implements Cloneable {
          private String name;
          
          public Prototype(String name) {
              this.name = name;
          }
          
          public void setName(String name) {
              this.name = name;
          }
          
          public String getName() {
              return name;
          }
          
          @Override
          protected Prototype clone() throws CloneNotSupportedException {
              return (Prototype) super.clone();
          }
      }
      
      public class PrototypePatternExample {
          public static void main(String[] args) {
              try {
                  Prototype prototype1 = new Prototype("Prototype 1");
                  Prototype prototype2 = prototype1.clone();
                  
                  prototype2.setName("Prototype 2");
                  
                  System.out.println(prototype1.getName());  // 输出: Prototype 1
                  System.out.println(prototype2.getName());  // 输出: Prototype 2
              } catch (CloneNotSupportedException e) {
                  e.printStackTrace();
              }
          }
      }
      
    • 使用场景:创建代价较大的对象,或者需要保证对象状态一致时。
    • Spring应用:Spring中通过scope="prototype"来创建每次调用都返回一个新的Bean实例。

结构型设计模式

  1. 适配器模式 (Adapter Pattern)

    • 原理:将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    • 代码实例
      interface Target {
          void request();
      }
      
      class Adaptee {
          void specificRequest() {
              System.out.println("Specific request");
          }
      }
      
      class Adapter implements Target {
          private Adaptee adaptee;
          
          public Adapter(Adaptee adaptee) {
              this.adaptee = adaptee;
          }
          
          public void request() {
              adaptee.specificRequest();
          }
      }
      
      public class AdapterPatternExample {
          public static void main(String[] args) {
              Adaptee adaptee = new Adaptee();
              Target adapter = new Adapter(adaptee);
              adapter.request();
          }
      }
      
    • 使用场景:当希望使用一个已有类,但其接口不符合要求时使用。
    • Spring应用HandlerAdapter是典型的适配器模式应用,负责将Controller处理的结果转化为用户能够理解的结果。
  2. 桥接模式 (Bridge Pattern)

    • 原理:将抽象部分与实现部分分离,使它们都可以独立变化。
    • 代码实例
      // 实现者接口
      interface Implementor {
          void operationImpl();
      }
      
      // 具体实现A
      class ConcreteImplementorA implements Implementor {
          public void operationImpl() {
              System.out.println("Concrete Implementor A operation");
          }
      }
      
      // 抽象类
      abstract class Abstraction {
          protected Implementor implementor;
          
          protected Abstraction(Implementor implementor) {
              this.implementor = implementor;
          }
          
          public abstract void operation();
      }
      
      // 扩展抽象类
      class RefinedAbstraction extends Abstraction {
          public RefinedAbstraction(Implementor implementor) {
              super(implementor);
          }
          
          public void operation() {
              implementor.operationImpl();
          }
      }
      
      public class BridgePatternExample {
          public static void main(String[] args) {
              Implementor implementor = new ConcreteImplementorA();
              Abstraction abstraction = new RefinedAbstraction(implementor);
              abstraction.operation();
          }
      }
      
    • 使用场景:系统需要在多个维度上独立扩展时,例如GUI系统的外观与功能。
    • Spring应用JdbcTemplate结合不同的数据库驱动就是桥接模式的应用。
  3. 组合模式 (Composite Pattern)

    • 原理:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
    • 代码实例
      interface Component {
          void operation();
      }
      
      class Leaf implements Component {
          public void operation() {
              System.out.println("Leaf operation");
          }
      }
      
      class Composite implements Component {
          private List<Component> children = new ArrayList<>();
          
          public void add(Component component) {
              children.add(component);
          }
          
          public void operation() {
              for (Component child : children) {
                  child.operation();
              }
          }
      }
      
      public class CompositePatternExample {
          public static void main(String[] args) {
              Composite root = new Composite();
              Leaf leaf1 = new Leaf();
              Leaf leaf2 = new Leaf();
              root.add(leaf1);
              root.add(leaf2);
              root.operation();
          }
      }
      
    • 使用场景:适用于需要表示树形结构的问题,例如文件系统、组织结构图。
    • Spring应用:Spring的BeanFactoryApplicationContext都可以看作是组合模式的应用。
  4. 装饰器模式 (Decorator Pattern)

    • 原理:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
    • 代码实例
      interface Component {
          void operation();
      }
      
      class ConcreteComponent implements Component {
          public void operation() {
              System.out.println("Concrete Component operation");
          }
      }
      
      class Decorator implements Component {
          protected Component component;
          
          public Decorator(Component component) {
              this.component = component;
          }
          
          public void operation() {
              component.operation();
          }
      }
      
      class ConcreteDecorator extends Decorator {
          public ConcreteDecorator(Component component) {
              super(component);
          }
          
          public void operation() {
              super.operation();
              System.out.println("Adding additional functionality");
          }
      }
      
      public class DecoratorPatternExample {
          public static void main(String[] args) {
              Component component = new ConcreteComponent();
              Component decorator = new ConcreteDecorator(component);
              decorator.operation();
          }
      }
      
    • 使用场景:需要动态扩展对象的功能时,例如给一个按钮添加多种不同的样式。
    • Spring应用:Spring中的BeanWrapper可以用于在运行时为Bean添加额外的功能。
  5. 外观模式 (Facade Pattern)

  • 原理:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这一接口使得这一子系统更加容易使用。
  • 代码实例
    class SubsystemA {
        void operationA() {
            System.out.println("Subsystem A operation");
        }
    }
    
    class SubsystemB {
        void operationB() {
            System.out.println("Subsystem B operation");
        }
    }
    
    class Facade {
        private SubsystemA subsystemA = new SubsystemA();
        private SubsystemB subsystemB = new SubsystemB();
        
        public void operation() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    public class FacadePatternExample {
        public static void main(String[] args) {
            Facade facade = new Facade();
            facade.operation();
        }
    }
    
  • 使用场景:提供一个简化的接口来访问复杂的子系统,例如简化数据库访问的外观类。
  • Spring应用JdbcTemplate是一个外观模式的实现,它简化了JDBC的操作。
  1. 享元模式 (Flyweight Pattern)
  • 原理:运用共享技术有效地支持大量细粒度的对象。
  • 代码实例
    class Flyweight {
        private String intrinsicState;
        
        public Flyweight(String state) {
            this.intrinsicState = state;
        }
        
        public void operation(String extrinsicState) {
            System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);
        }
    }
    
    class FlyweightFactory {
        private Map<String, Flyweight> flyweights = new HashMap<>();
        
        public Flyweight getFlyweight(String key) {
            if (!flyweights.containsKey(key)) {
                flyweights.put(key, new Flyweight(key));
            }
            return flyweights.get(key);
        }
    }
    
    public class FlyweightPatternExample {
        public static void main(String[] args) {
            FlyweightFactory factory = new FlyweightFactory();
            Flyweight flyweight1 = factory.getFlyweight("State1");
            Flyweight flyweight2 = factory.getFlyweight("State2");
            Flyweight flyweight3 = factory.getFlyweight("State1");
            
            flyweight1.operation("Extrinsic1");
            flyweight2.operation("Extrinsic2");
            flyweight3.operation("Extrinsic3");
        }
    }
    
  • 使用场景:适用于需要大量相似对象的场景,例如字符、图片等重复出现的情况。
  • Spring应用:Spring中的缓存机制可以看作是享元模式的应用。
  1. 代理模式 (Proxy Pattern)
  • 原理:为其他对象提供一种代理以控制对这个对象的访问。
  • 代码实例
    interface Subject {
        void request();
    }
    
    class RealSubject implements Subject {
        public void request() {
            System.out.println("Real subject request");
        }
    }
    
    class Proxy implements Subject {
        private RealSubject realSubject;
        
        public void request() {
            if (realSubject == null) {
                realSubject = new RealSubject();
            }
            realSubject.request();
        }
    }
    
    public class ProxyPatternExample {
        public static void main(String[] args) {
            Subject proxy = new Proxy();
            proxy.request();
        }
    }
    
  • 使用场景:需要控制对对象的访问,例如懒加载、安全控制等。
  • Spring应用:AOP(面向切面编程)就是代理模式的一个典型应用,通过代理对方法进行增强。

行为型设计模式

  1. 责任链模式 (Chain of Responsibility Pattern)
  • 原理:为请求创建一个接收者对象的链。每个对象沿着链处理请求,直到有一个对象处理它为止。
  • 代码实例
    abstract class Handler {
        protected Handler next;
        
        public void setNext(Handler next) {
            this.next = next;
        }
        
        public abstract void handleRequest(String request);
    }
    
    class ConcreteHandlerA extends Handler {
        public void handleRequest(String request) {
            if (request.equals("A")) {
                System.out.println("Handler A handled request");
            } else if (next != null) {
                next.handleRequest(request);
            }
        }
    }
    
    class ConcreteHandlerB extends Handler {
        public void handleRequest(String request) {
            if (request.equals("B")) {
                System.out.println("Handler B handled request");
            } else if (next != null) {
                next.handleRequest(request);
            }
        }
    }
    
    public class ChainOfResponsibilityExample {
        public static void main(String[] args) {
            Handler handlerA = new ConcreteHandlerA();
            Handler handlerB = new ConcreteHandlerB();
            handlerA.setNext(handlerB);
            
            handlerA.handleRequest("B");
        }
    }
    
  • 使用场景:有多个对象可以处理一个请求时,例如审批流程。
  • Spring应用:Spring Security中的过滤器链就是责任链模式的典型应用。
  1. 命令模式 (Command Pattern)
  • 原理:将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化。
  • 代码实例
    interface Command {
        void execute();
    }
    
    class ConcreteCommand implements Command {
        private Receiver receiver;
        
        public ConcreteCommand(Receiver receiver) {
            this.receiver = receiver;
        }
        
        public void execute() {
            receiver.action();
        }
    }
    
    class Receiver {
        public void action() {
            System.out.println("Receiver action");
        }
    }
    
    public class CommandPatternExample {
        public static void main(String[] args) {
            Receiver receiver = new Receiver();
            Command command = new ConcreteCommand(receiver);
            command.execute();
        }
    }
    
  • 使用场景:需要对请求排队、记录日志或者支持撤销操作时。
  • Spring应用@Async注解使用命令模式来异步执行命令。
  1. 解释器模式 (Interpreter Pattern)
  • 原理:给定一个语言,定义它的文法表示,并定义一个解释器来处理这个文法中的句子。
  • 代码实例
    interface Expression {
        int interpret();
    }
    
    class Number implements Expression {
        private int number;
        
        public Number(int number) {
            this.number = number;
        }
        
        public int interpret() {
            return number;
        }
    }
    
    class Add implements Expression {
        private Expression left;
        private Expression right;
        
        public Add(Expression left, Expression right) {
            this.left = left;
            this.right = right;
        }
        
        public int interpret() {
            return left.interpret() + right.interpret();
        }
    }
    
    public class InterpreterPatternExample {
        public static void main(String[] args) {
            Expression left = new Number(5);
            Expression right = new Number(10);
            Expression add = new Add(left, right);
            System.out.println("Result: " + add.interpret());
        }
    }
    
  • 使用场景:当需要解释一种特定语言时,例如数学表达式的计算。
  • Spring应用:Spring中的SpEL(Spring Expression Language)就是解释器模式的实现。
  1. 迭代器模式 (Iterator Pattern)
  • 原理:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
  • 代码实例
    interface Iterator {
        boolean hasNext();
        Object next();
    }
    
    class ConcreteIterator implements Iterator {
        private List<Object> items;
        private int position = 0;
        
        public ConcreteIterator(List<Object> items) {
            this.items = items;
        }
        
        public boolean hasNext() {
            return position < items.size();
        }
        
        public Object next() {
            return items.get(position++);
        }
    }
    
    class Aggregate {
        private List<Object> items = new ArrayList<>();
        
        public void addItem(Object item) {
            items.add(item);
        }
        
        public Iterator createIterator() {
            return new ConcreteIterator(items);
        }
    }
    
    public class IteratorPatternExample {
        public static void main(String[] args) {
            Aggregate aggregate = new Aggregate();
            aggregate.addItem("Item1");
            aggregate.addItem("Item2");
            aggregate.addItem("Item3");
            
            Iterator iterator = aggregate.createIterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }
    }
    
  • 使用场景:需要遍历一个聚合对象时,例如Java中的集合遍历。
  • Spring应用:Spring的ListableBeanFactory可以使用迭代器模式来遍历Bean。
  1. 中介者模式 (Mediator Pattern)
  • 原理:用一个中介对象封装一系列对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散。
  • 代码实例
    interface Mediator {
        void notify(Component sender, String event);
    }
    
    class ConcreteMediator implements Mediator {
        private ComponentA componentA;
        private ComponentB componentB;
        
        public void setComponentA(ComponentA componentA) {
            this.componentA = componentA;
        }
        
        public void setComponentB(ComponentB componentB) {
            this.componentB = componentB;
        }
        
        public void notify(Component sender, String event) {
            if (event.equals("A")) {
                componentB.react();
            }
        }
    }
    
    class Component {
        protected Mediator mediator;
        
        public Component(Mediator mediator) {
            this.mediator = mediator;
        }
    }
    
    class ComponentA extends Component {
        public ComponentA(Mediator mediator) {
            super(mediator);
        }
        
        public void triggerEvent() {
            System.out.println("Component A triggered event");
            mediator.notify(this, "A");
        }
    }
    
    class ComponentB extends Component {
        public ComponentB(Mediator mediator) {
            super(mediator);
        }
        
        public void react() {
            System.out.println("Component B reacting to event");
        }
    }
    
    public class MediatorPatternExample {
        public static void main(String[] args) {
            ConcreteMediator mediator = new ConcreteMediator();
            ComponentA componentA = new ComponentA(mediator);
            ComponentB componentB = new ComponentB(mediator);
            
            mediator.setComponentA(componentA);
            mediator.setComponentB(componentB);
            
            componentA.triggerEvent();
        }
    }
    
  • 使用场景:当对象之间的交互复杂且呈现网状结构时。
  • Spring应用:Spring的ApplicationEventPublisher就是中介者模式的应用。
  1. 备忘录模式 (Memento Pattern)
  • 原理:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后恢复它。
  • 代码实例
    class Memento {
        private String state;
        
        public Memento(String state) {
            this.state = state;
        }
        
        public String getState() {
            return state;
        }
    }
    
    class Originator {
        private String state;
        
        public void setState(String state) {
            this.state = state;
        }
        
        public Memento saveState() {
            return new Memento(state);
        }
        
        public void restoreState(Memento memento) {
            this.state = memento.getState();
        }
    }
    
    public class MementoPatternExample {
        public static void main(String[] args) {
            Originator originator = new Originator();
            originator.setState("State1");
            
            Memento memento = originator.saveState();
            originator.setState("State2");
            
            System.out.println("Current State: " + originator.state);
            originator.restoreState(memento);
            System.out.println("Restored State: " + originator.state);
        }
    }
    
  • 使用场景:需要保存对象的历史状态以便后续恢复时。
  • Spring应用:Spring中没有直接的备忘录模式实现,但可以通过缓存等机制保存和恢复状态。
  1. 观察者模式 (Observer Pattern)
  • 原理:定义对象间一种一对多的依赖关系,以便当一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动更新。
  • 代码实例
    interface Observer {
        void update(String message);
    }
    
    class ConcreteObserver implements Observer {
        public void update(String message) {
            System.out.println("Received update: " + message);
        }
    }
    
    class Subject {
        private List<Observer> observers = new ArrayList<>();
        
        public void addObserver(Observer observer) {
            observers.add(observer);
        }
        
        public void notifyObservers(String message) {
            for (Observer observer : observers) {
                observer.update(message);
            }
        }
    }
    
    public class ObserverPatternExample {
        public static void main(String[] args) {
            Subject subject = new Subject();
            Observer observer1 = new ConcreteObserver();
            Observer observer2 = new ConcreteObserver();
            
            subject.addObserver(observer1);
            subject.addObserver(observer2);
            
            subject.notifyObservers("State has changed!");
        }
    }
    
  • 使用场景:当一个对象状态变化需要通知多个其他对象时,例如消息通知系统。
  • Spring应用:Spring中的事件机制就是观察者模式的应用。
  1. 状态模式 (State Pattern)
  • 原理:允许一个对象在其内部状态发生改变时改变其行为,看起来就像改变了它的类。
  • 代码实例
    interface State {
        void handle();
    }
    
    class ConcreteStateA implements State {
        public void handle() {
            System.out.println("Handling state A");
        }
    }
    
    class ConcreteStateB implements State {
        public void handle() {
            System.out.println("Handling state B");
        }
    }
    
    class Context {
        private State state;
        
        public void setState(State state) {
            this.state = state;
        }
        
        public void request() {
            state.handle();
        }
    }
    
    public class StatePatternExample {
        public static void main(String[] args) {
            Context context = new Context();
            State stateA = new ConcreteStateA();
            State stateB = new ConcreteStateB();
            
            context.setState(stateA);
            context.request();
            
            context.setState(stateB);
            context.request();
        }
    }
    
  • 使用场景:对象行为依赖于状态变化,例如游戏角色状态。
  • Spring应用:Spring中的StatefulRetryOperationsInterceptor实现了状态模式。
  1. 策略模式 (Strategy Pattern)
  • 原理:定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可以独立于使用它的客户而变化。
  • 代码实例
    interface Strategy {
        void execute();
    }
    
    class ConcreteStrategyA implements Strategy {
        public void execute() {
            System.out.println("Executing Strategy A");
        }
    }
    
    class ConcreteStrategyB implements Strategy {
        public void execute() {
            System.out.println("Executing Strategy B");
        }
    }
    
    class Context {
        private Strategy strategy;
        
        public Context(Strategy strategy) {
            this.strategy = strategy;
        }
        
        public void executeStrategy() {
            strategy.execute();
        }
    }
    
    public class StrategyPatternExample {
        public static void main(String[] args) {
            Context context = new Context(new ConcreteStrategyA());
            context.executeStrategy();
            
            context = new Context(new ConcreteStrategyB());
            context.executeStrategy();
        }
    }
    
  • 使用场景:需要动态选择算法的场景,例如支付方式的选择。
  • Spring应用TransactionTemplate使用不同的事务策略。
  1. 模板方法模式 (Template Method Pattern)
  • 原理:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下重定义算法的某些步骤。
  • 代码实例
    abstract class AbstractClass {
        final void templateMethod() {
            primitiveOperation1();
            primitiveOperation2();
        }
        
        abstract void primitiveOperation1();
        abstract void primitiveOperation2();
    }
    
    class ConcreteClass extends AbstractClass {
        void primitiveOperation1() {
            System.out.println("Primitive Operation 1");
        }
        
        void primitiveOperation2() {
            System.out.println("Primitive Operation 2");
        }
    }
    
    public class TemplateMethodPatternExample {
        public static void main(String[] args) {
            AbstractClass concrete = new ConcreteClass();
            concrete.templateMethod();
        }
    }
    
  • 使用场景:适用于多个子类有公共行为且逻辑相同时,例如实现通用的数据处理流程。
  • Spring应用JdbcTemplateHttpServlet中的doGet()doPost()等方法都是模板方法模式的应用。
  1. 访问者模式 (Visitor Pattern)
  • 原理:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
  • 代码实例
    interface Visitor {
        void visit(Element element);
    }
    
    interface Element {
        void accept(Visitor visitor);
    }
    
    class ConcreteElementA implements Element {
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
    }
    
    class ConcreteVisitor implements Visitor {
        public void visit(Element element) {
            System.out.println("Visiting element");
        }
    }
    
    public class VisitorPatternExample {
        public static void main(String[] args) {
            Element element = new ConcreteElementA();
            Visitor visitor = new ConcreteVisitor();
            element.accept(visitor);
        }
    }
    
  • 使用场景:需要对对象结构中的元素进行操作且操作易变时。
  • Spring应用:Spring的BeanPostProcessor可以视为访问者模式的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905283.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信支付宝小程序SEO优化的四大策略

在竞争激烈的小程序市场中&#xff0c;高搜索排名意味着更多的曝光机会和潜在用户。SEO即搜索引擎优化&#xff0c;对于小程序而言&#xff0c;主要指的是在微信小程序商店中提高搜索排名&#xff0c;从而增加曝光度和用户访问量。有助于小程序脱颖而出&#xff0c;提升品牌知名…

Java面试经典 150 题.P27. 移除元素(002)

本题来自&#xff1a;力扣-面试经典 150 题 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台https://leetcode.cn/studyplan/top-interview-150/ 题解&#xff1a; class Solution {public int removeElement(int[] nums, int…

新160个crackme - 088-[KFC]fish‘s CrackMe

运行分析 需破解用户名和RegKey PE分析 C程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida函数窗口逐个查看&#xff0c;找到关键函数sub_401440 ida无法动调&#xff0c;需使用OD&#xff0c;启用StrongOD插件才可以动调ida静态分析&#xff0c;逻辑如下&…

[Linux关键词]unmask,mv,dev/pts,stdin stdout stderr,echo

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;大大会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

你知道你的顾客长什么样儿吗 | 顾客画像的魅力

0139岁、亚裔、女性和 Costco 「一位 39 岁的亚裔女性&#xff0c;年收入可达到 12.5 万美金」&#xff0c;这是 Numerator 描绘的 Costco 2023 年的顾客画像。而一个典型的 Costco 会员每两周的周末会去一次 Costco&#xff08;约为每年前往Costco采买30次&#xff09;&…

报表制作神器,轻松应对复杂报表

在企业运营中&#xff0c;面对海量数据和复杂报表的处理&#xff0c;不少公司都希望能有一款便捷、高效的工具来帮忙完成各类报表任务。今天要给大家推荐的是一款备受用户好评的国产报表工具——山海鲸报表&#xff0c;它不仅能处理复杂的数据表&#xff0c;还拥有丰富的可视化…

auto 项目笔记

基础设置 1.设置python目录为根路径 1. merge_with_history debug (1) coomon.yaml 修改 最下边的 root: /mnt/sdb/daimler/EHPV2/Ruiming_InternalDaily (2) 环境变量设置为1时 不走此步骤做的任何处理&#xff0c;直把上步数据接透传出去 2.

亚马逊云免费Amazon CloudFront服务

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 引言一、亚马逊云科技简介二、亚马逊云科技免费资源注册信息准备注册亚马逊云科技账号 三、…

企业应该采用和支持网络安全的几个实践

令人惊讶的是&#xff0c;网络安全可以像遵循最佳实践一样简单&#xff0c;理想情况下应该将其融入企业文化本身。在这篇文章中了解更多。 网络安全的重要性 在当今的网络安全期望中&#xff0c;软件工程师应该优先考虑他们的计算机系统和内部IT网络的安全性。我认为严重依赖…

升降压斩波【电力电子技术5章】

降压斩波&#xff1a; 升压斩波&#xff1a; 升降压斩波&#xff1a;

细说 ThreadPool(线程池)使用与优势以及实现方式

细说 ThreadPool&#xff08;线程池&#xff09;使用与优势https://mp.weixin.qq.com/s?__bizMzkzMTY0Mjc0Ng&mid2247485102&idx1&sndc578203c855e479a5b678b99b0f46b6&chksmc266aabbf51123ade562bf61230c3665886ae6c38fec790d2d9fb83afa805a1402d81086263c#r…

一种将树莓派打造为游戏机的方法——Lakka

什么是Lakka&#xff1f; Lakka是一款Linux发行版&#xff0c;轻量级的&#xff0c;可将小型计算机转变为一台复古游戏机。 图1-Lakka官网&#xff0c;见参考链接[1] Lakka是RetroArch和libretro生态系统下的官方操作系统&#xff0c;前者RetroArch是模拟器、游戏引擎和媒体播…

中医知识图谱之可视化模糊查询+力导向图+环形图的布局切换

后端通过springboot链接neo4j实现 前端通过echarts的关系图组件实现&#xff0c;echarts版本是4.2.1(有点老的版本但是不影响&#xff09; 实现功能是模糊查询中药方剂和药材的关系图谱 1 知识图谱可视化 黄色标识药方方剂、蓝色是药材&#xff0c;支持切换布局、支持模糊搜索…

【春秋云镜】CVE-2023-27179

CVE-2023-27179 CVE-2023-27179 是一个影响 Apache Doris 的漏洞。Apache Doris 是一款用于交互式分析的高性能数据库&#xff0c;特别适用于处理大规模的结构化数据。该漏洞属于权限提升漏洞&#xff0c;允许未授权用户以管理员身份执行敏感操作。 具体细节 漏洞类型&#…

Mybatis使用和原理

Mybatis使用和原理 1、ORM架构2、Spring整合MyBatis使用2.1 添加maven依赖2.2 配置数据源2.3 创建实体类2.4 创建 MyBatis Mapper2.4.1 使用MyBatis注解2.4.2 使用XML方式 2.5 Service 层 3、Spring整合Hibernate使用3.1 添加maven依赖3.2 配置数据源3.3 创建实体类3.4 创建 Re…

C/C++ 矩阵的QR分解

#include <iostream> #include <vector> using namespace std;int main() /* 矩阵A的QR分解*/ {// 动态分配内存int m 3; // 行数int n 3; // 列数// 初始化矩阵Adouble A[3][3] {{1, 2, 2},{2, 1, 2},{1, 2, 1}};double R[3][3] { 0 };double Q[3][3] { 0 };…

Transformer-BiGRU多特征输入时间序列预测(Pytorch)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Transformer-BiGRU多特征输入时间序列预测 可以做风电预测&#xff0c;光伏预测&#xff0c;寿命预测&#xff0c;浓度预测等。 Python代码&#xff0c;基于Pytorch编写 1.多特征输入单步预测&#xff0c;多步预测&a…

Unity hub登录时一直无法进入license

直接只卸载unity hub&#xff0c;然后重新下载unity hub安装即可&#xff0c;重新登录即可。 有时会自动关联安装的位置&#xff0c;如果不能&#xff0c;则手动定位添加即可。 网上各种修复的方法操作费时费力。

【MySQL】架构

1. MySQL架构基本理解 与餐厅就餐类比理解 每次数据库查询就像一次餐厅服务 应用程序发出查询相当于点菜MySQL解析和执行查询&#xff0c;后厨根据订单制作食物事务管理保证数据的一致性&#xff0c;类似于结账的时候保证账单正确查询的时候考虑优化器&#xff0c;类似于厨师选…

4款专业音频在线剪辑工具帮你开启创意之路。

音频在线剪辑工具能够为我们提供很大的便利&#xff0c;对于不管是专业的音乐制作人还是音频创作爱好者来说&#xff0c;都能借助一些音频编辑工具来充分发挥自己的创意。所以这一次&#xff0c;我要给大家介绍几个专业方便的音频剪辑工具。 1、福昕音频在线 直达链接&#x…