设计模式之禅

单例模式

定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

饿汉式

public class Singleton{
  private static final Singleton singleton = new Singleton();
  private Singleton(){
  }

  public static Singleton getSingleton(){
    return singleton;
  }
  
  //类中其他方法,尽量是static
  public static void doSometing(){
  }
}

懒汉式

线程不安全

public class Singleton{
  public static Singleton singleton = null;

  private Singleton(){
  }

  public static Singleton getSingleton(){
    if(singleton == null){
      singleton = new Singleton();
    }
    return singleton;
  }
}

工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到子类。

通用代码

抽象产品类

public abstract class Product{
  // 产品类的公共方法
  public void method1(){}

  // 抽象方法
  public abstract void method2();
}

具体产品类

public class ConcreteProduct1 extends Product{
  public void method2(){}
}
public class ConcreteProduct2 extends Product{
  public void method2(){}
}

抽象工厂类

public abstract class Creator{
  public abstract <T extends Product> T createProduct(Class<T> c);
}

具体工厂类

pubcic class ConcreteCreator extends Creator{
  public <T extends Product> T createProduct(Class<T> c){
    Product product = null;
    try {
    product = (Product)Class.forName(c.getName()).newInstance();
    } catch (Exception e) {
      //异常处理
    }
    return (T)product;
  }
}

场景类

public class Client {
  public static void main(String[] args){
      Creator creator = new ConcreteCreator();
      Product product = creator.createProduct(ConcreteProduct1.class);
      // 继续业务处理
  }
}

抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口。而且无需指定他们的具体类。

通用代码

抽象产品类

public abstaract class AbstractProductA{
  // 每个产品共有的方法
  public void shareMethod(){
  }

  // 每个产品相同方法不同实现
  public abstract void doSomething();
}

产品A1的实现类

public class ProductA1 extends AbstractProductA{
  public void doSomething(){
    System.out.println("产品A1的实现方法");
  }
}

产品A2的实现类

public class ProductA2 extends AbstractProductA{
  public void doSomething(){
    System.out.println("产品A2的实现方法");
  }
}

产品B类似,B1,B2,不赘述

抽象工厂类

public abstract class AbstractCreator{
  // 创建A产品家族
  public abstract AbstractProductA createProductA();

  // 创建B产品家族
  public abstract AbstractProductB createProductB();
}

注意:有N个产品族,在抽象工厂类中就应该有N个创建方法

产品等级1的实现类

public class Creator1 extends AbstractCreator{
  // 只生产产品等级为1的A产品
  public AbstractProductA createProductA(){
    return new ProductA1();
  }
  // 只生产产品等级为1的B产品
  public AbstractProductB createProductB(){
    return new ProductB1();
  }
}

产品等级2的实现类

public class Creator2 extends AbstractCreator{
  // 只生产产品等级为2的A产品
  public AbstractProductA createProductA(){
    return new ProductA2();
  }
  // 只生产产品等级为2的B产品
  public AbstractProductB createProductB(){
    return new ProductB2();
  }
}

注意:有M个产品等级就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务

场景类

public class Client{
  public static void main(Stringp[] args){
    // 定义出两个工厂
    AbstractCreator creator1 = new Creator1();
    AbstractCreator creator2 = new Creator2();

    // 产生A1对象
    AbstractProductA a1 = creator1.createProductA();
    // 产生A2对象
    AbstractProductA a2 = creator2.createProductA();
    // 产生B1对象
    AbstractProductB b1 = creator1.createProductB();
    // 产生B2对象
    AbstractProductB b2 = creator2.createProductB();
    
    /*
     *为所欲为
     */

  }
}

模板方法模式

定义:定义一个操作中的算法的框架,而将一些步骤延迟到子类。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模式中的角色:

1.抽象模板,他的方法分两类。

  • 基本方法:基本方法也叫基本操作,是由子类实现的方法,并且在模板方法中被调用。
  • 模板方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度。完成固定的逻辑。

2.具体模板:实现父类所定义的一个或多个抽象方法,也就是父类定义的基本方法中在子类中得以实现。

通用代码:

抽象模板类:

public abstract class AbstractClass{
  // 基本方法
  protected abstract void doSomething();
  // 基本方法
  protected abstract void doAnything();
  // 模板方法
  public void templateMethod(){
    /*
     *调用基本方法,完成相关逻辑
     */
    this.doAnything();
    this.doSomething();
  }
}

具体模板类:

public class ConcreteClass1 extends AbstractClass{
  // 实现基本方法
  protected void doAnything(){
    // 业务逻辑处理
  }
  protected void doSomething(){
    //业务逻辑处理
  }
}

public class ConcreteClass2 extends AbstractClass{
  // 实现基本方法
  protected void doAnything(){
    // 业务逻辑处理
  }
  protected void doSomething(){
    //业务逻辑处理
  }
}

场景类:

public class Client{
  public static void main(String[] args){
    AbstractClass class1 = new ConcreteClass1();
    AbstractClass class2 = new ConcreteClass2();
    // 调用模板方法
    class1.templateMethod();
    class2.templateMehthod();
  }
}

注意:抽象模板中的基本方法尽量设计为protected类型,符合迪米特法则,不需要暴露的属性或方法尽量不要设置为protected类型。实现类若非必要,尽量不要扩大父类中的访问权限。

建造者模式

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

模式中的角色

  • Product产品类:通常是实现了模板方法模式,也就是有模板方法和基本方法。
  • Builder抽象建造者:规范产品的组建,一般是由子类实现。
  • ConcreteBuilder具体建造者类:实现抽象类定义的所有方法,并且返回一个组建好的对象。
  • Director导演类:负责安排已有模块的顺序,然后告诉Builder开始建造。

通用代码:

产品类:

public class Product{
  public void doSomething(){
    // 独立业务处理
  }
}

抽象建造者:

public abstract class Builder{
  // 设置产品的不同部分,以获得不同的产品
  public abstract void setPart();
  // 建造产品
  public abstract Product buildProduct();
}

具体建造者:

public class ConcreteProduct extends Builder{
  private Product product = new Product();
  // 设置产品零件
  public void setPart(){
    /*
     *产品类内的逻辑处理
     */
  }
  // 组建一个产品
  public Product buildProduct(){
    return product;
  }
}

导演类:

public class Director{
  private Builder builder =  new ConcreteProduct();
  // 创建不同的产品
  public Product getAProduct(){
    builder.setPart();
    /*
     * 设置不同的零件,产生不同的产品
     */
    return builder.buildProduct();
  } 
}

代理模式

定义:为其他对象提供一种代理以控制对这个对象的访问。

模式中的角色

  • Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口。
  • RealSubject具体主题角色:也叫做被委托角色、被代理角色,是业务逻辑的具体执行者。
  • Proxy代理主题角色:也叫委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

通用代码

抽象主题类:

public interface Subject{
  // 定义一个方法
  public void request();
}

真实主题类:

public class RealSubject implements Subject{
  // 实现方法
  public void request(){
    // 业务逻辑处理
  }
}

代理类:

public class Proxy implements Subject{
  // 要代理哪个实现类
  private Subject subject = null;
  // 默认被代理者
  public Proxy(){
    this.subject = new RealSubject();
  }
  // 通过构造函数传递代理者
  public Proxy(Object...objects){
  }
  // 实现接口中定义的方法
  public void request(){
    this.before();
    this.subject.request();
    this.after();
  }
  // 预处理
  private void before(){
    // do something
  }
  // 善后处理
  private void after(){
    // do something
  }

}

代理模式扩展:普通代理、强制代理、动态代理

...

原型模式

定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
核心为clone方法
注意:深拷贝和浅拷贝

通用代码

public class PrototypeClass implements Cloneanble{
  // 覆写父类Object方法
  @Override
  public PrototypeClass prototypeClass = null;
  try{
    prototypeClass = (PrototypeClass)super.clone();
  } catch(CloneNotSupportedException e){
    //异常处理
  }
  return prototypeClass;
}

中介者模式

定义:用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

模式中的各角色

  • Mediator抽象中介者角色:抽象中介者角色定义统一的接口,用于各同事同时之间的通信。
  • Concrete Mediator具体中介者角色:具体中介者角色通过协调各同事角色实现写作行为,因此它必须依赖于各个同事角色。
  • Colleague同事角色:每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候吗,一定要通过中介者角色协作。每个同事类的行为分两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为。与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。

通用代码

通用抽象中介者

public abstract class Mediator{
  // 定义同事类
  protected ConcreteColleague1 c1;
  protected ConcreteColleague2 c2;
  // 通过getter/setter方法把同时注入进来
  public ConcreteColleague1 getC1(){
    return c1;
  }
  public void setC1(ConcreteColleague1 c1){
    this.c1 = c1;
  }
  public ConcreteColleague2 getC2(){
    return c2;
  }
  public void setC2(ConcreteColleague1 c2){
    this.c2 = c2;
  }
  // 中介者模式的业务逻辑
  public abstract void doSomething1();
  public abstract void doSomething2();
}

通用中介者

public class ConcreteMediator extends Mediator{
  @Override
  public void doSomething1(){
    // 调用同事类的方法,只要public方法都可以调用
    super.c1.selfMethod1();
    super.c2.selfMethod2();
  }
  @Override
  public void doSomething2(){
    // 调用同事类的方法,只要public方法都可以调用
    super.c1.selfMethod1();
    super.c2.selfMethod2();
  }
}

抽象同事类

public abstract class Colleague{
  protected Mediator mediator;
  public Colleague(Mediator _mediator){
    this.mediator = _mediator;
  }
}

具体同事类

public class ConcreteColleague1 extends Colleague{
  //通过构造函数传递中介者
  public ConcreteColleague1(Mediator _mediator){
    super(_mediator);
  }
  // 自有方法 self-method
  public void selfMethod1(){
    // 处理自己的业务逻辑
  }
  // 依赖方法 dep-method
  public void depMethod1(){
    // 处理自己的业务逻辑
    // 自己不能处理的业务逻辑,委托给中介者处理
    super.mediator.doSomething();
  }
}

public class ConcreteColleague2 extends Colleague{
  //通过构造函数传递中介者
  public ConcreteColleague2(Mediator _mediator){
    super(_mediator);
  }
  // 自有方法 self-method
  public void selfMethod2(){
    // 处理自己的业务逻辑
  }
  // 依赖方法 dep-method
  public void depMethod2(){
    // 处理自己的业务逻辑
    // 自己不能处理的业务逻辑,委托给中介者处理
    super.mediator.doSomething();
  }
}

为什么同事类要使用构造函数注入中介者,而中介者使用getter/setter方式注入同事类?:因为同事类必须有中介者,而中介者缺可以只有部分同事类。

命令模式

定义:高内聚的模式。将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

模式中的角色

  • Receive接收者角色:该角色就是干活的角色,命令传递到这里时应该被执行的。
  • Command命令角色:需要执行的所有命令都在这里声明。
  • Invoker调用者角色:接收到命令,并执行命令。

通用代码

Receiver类:

public abstract class Receiver{
  // 抽象接收者,定义每个接收者都必须完成的业务
  public abstract void doSomething(){
  }
}

具体的Receiver接收者:

public class ConcreteReceiver1 extends Receiver{
  // 每个接收者都必须处理一定的业务逻辑
  public void doSomething(){
  }
}
public class ConcreteReceiver2 extends Receiver{
  // 每个接收者都必须处理一定的业务逻辑
  public void doSomething(){
  }
}

抽象的Command类:

public abstract class Command{
  // 每个命令都必须有一个执行命令的方法
  public abstract void execute();
}

具体的Command类:

public class ConcreteCommand1 extends Command{
  // 对哪个Receiver类进行命令处理
  private Receiver receiver;
  // 构造函数传递接收者
  public ConcreteCommand1(Receiver _receiver){
    this.receiver = _receiver;
  }
  // 必须实现一个命令
  public void execute(){
    // 业务处理
    this.receiver.doSomething();
  }
}
public class ConcreteCommand2 extends Command{
  // 对哪个Receiver类进行命令处理
  private Receiver receiver;
  // 构造函数传递接收者
  public ConcreteCommand2(Receiver _receiver){
    this.receiver = _receiver;
  }
  // 必须实现一个命令
  public void execute(){
    // 业务处理
    this.receiver.doSomething();
  }
}

调用者Invoker类:

publci class Invoker{
  private Command command;
  // 接收命令
  public void setCommand(Command _command){
    this.command = _command;
  }
  // 执行命令
  public void action(){
  }
}

场景类:

public class Client{
  public static void main(String[] args){
    // 首先声明调用者Invoker
    Invoker invoker = new Invoker();
    // 定义接收者
    Receiver receiver = new ConcreteReceiver1();
    // 定义一个发送给接收者的命令
    Command command = new ConcreteCommand1(receiver);
    // 把命令交给调用者去执行
    invoker.setCommand(command);
    invoker.action();
  }
}

责任链模式

定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。核心在”链“。

通用代码

抽象处理者:

public abstract class Handler{
  private Handler nextHandler;
  // 每个处理者都必须对请求做出处理
  public final Response handleMessage(Request request){
    Response response = null;
    // 判断是否是自己的处理级别
    if(this.getHandlerLevel().equals(request.getRequestLevel())){
      response = this.echo(request);
    }else{ // 不属于自己的处理级别
      // 判断是否有下一个处理者
      if(this.nextHandler != null){
        response = this.nextHandler.handleMessage(request);
      }else{
        // 没有适当的处理者,业务自行处理
      }
    }
    return response;
  }
  // 设置下一个处理者是谁
  public void setNext(Handler _handler){
    this.nextHandler = _handler;
  }
  // 每个处理者都有一个处理级别
  protected abstract Level getHandlerLevel();
  // 每个处理者都必须实现处理任务
  protected abstract Response echo(Request request);
}

具体处理者:

public class ConcreteHandler1 extends Handler{
  // 定义自己的处理逻辑
  protected Response echo(Request request){
    // 完成处理逻辑
    return null;
  }
  // 设置自己的处理级别
  protected Level getHandlerLevel(){
    // 设置自己的处理级别
    return null;
  }
}
public class ConcreteHandler2 extends Handler{
  // 定义自己的处理逻辑
  protected Response echo(Request request){
    // 完成处理逻辑
    return null;
  }
  // 设置自己的处理级别
  protected Level getHandlerLevel(){
    // 设置自己的处理级别
    return null;
  }
}

模式中有关框架的代码:

public class Level{
  // 定义一个请求和处理等级
}
public class Request{
  // 请求等级
  public Level getRequestLevel(){
    return null;
  }
}
public class Response{
  // 处理返回的数据
}

场景类:

public Client{
  public static void main(String[] args){
    // 声明所有的处理节点
    Handler handler1 = new ConcreteHandler1();
    Handler handler2 = new ConcreteHandler2();
    Handler handler3 = new ConcreteHandler3();
    // 设置链中的阶段顺序1-->2-->3
    handler1.setNext(handler2);
    handler2.setNext(hanlder3);
    // 提交请求,返回结果
    Response response = handler1.handleMessage(new Request());
  }
}

装饰模式

定义:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

模式中的角色说明

  • Component抽象构件:Component是一个接口或者抽象类,就是定义最核心的对象,也就是最原始的对象
  • ConcreteComponent:具体构件
  • Decorator装饰角色:一般是抽象类,里面不一定有抽象方法,但是属性里一定有一个private变量指向Component抽象构建。
  • 具体装饰角色:ConcreteDecoratorA,ConcreteDecoratorB,...

通用代码

抽象构件:

public abstract class Component{
  // 抽象的方法
  public abstract void operate();
}

具体构件:

public class ConcreteComponent extendsComponent{
  // 具体实现
  @Override
  public void operate(){
    System.out.println("do Something");
  }
}

抽象装饰者:

public abstract class Decorator extends Component{
  private Component component = null;
  // 通过构造函数传递被修饰者
  public Decorator(Component _component)P
    this.component = _component;
  }
  // 委托给被修饰者执行
  @Override
  public void operate(){
    this.component.operate();
  }

具体的装饰类:

public class ConcreteDecorator1 extends Decorator{
  // 定义被修饰者
  public ConcreteDecorator1(Component _component){
    super(_component);
  }
  // 定义自己的修饰方法
  private void method1{
    System.out.println("method1 修饰");
  }
  // 重写父类的Operation方法
  public void operate(){
    this.method1();
    super.operate();
  }
}
public class ConcreteDecorator2 extends Decorator{
  // 定义被修饰者
  public ConcreteDecorator2(Component _component){
    super(_component);
  }
  // 定义自己的修饰方法
  private void method2{
    System.out.println("method2 修饰");
  }
  // 重写父类的Operation方法
  public void operate(){
    super.operate();
    this.method2();
  }
}

场景类:

public class Client{
  public static void main(String[] args){
    Component component = new ConcreteComponent();
    // 第一次修饰
    component = new ConcreteDecorator1(component);
    // 第二次修饰
    component = new ConcreteDecorator2(component);
    // 修饰后运行
    component.operate();
  }
}

策略模式

定义:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。

模式中的角色

  • Context封装角色:它也叫做上下文角色。起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
  • Strategy抽象策略角色:策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
  • ConcreteStrategy具体策略角色

通用源码

抽象的策略角色:

public interface Strategy{
  // 策略模式的运算法则
  public void doSomething();
}

具体策略角色:

public class ConcreteStrategy1 implements Strategy{
  public void doSomething{
    System.out.println("具体策略1的运算法则");
  }
}
public class ConcreteStrategy2 implements Strategy{
  public void doSomething{
    System.out.println("具体策略2的运算法则");
  }
}

封装角色:

public class Context{
  // 抽象策略
  private Strategy strategy = null;
  // 构造函数设置具体策略
  public Context(Strategy _strategy){
    this.strategy = _strategy;
  }
  // 封装后的策略方法
  public void doAnything(){
    this.strategy.doSomething();
  }
}

高层模块:

public class Client{
  public static void main(String[] args){
    // 声明一个具体的策略
    Strategy strategy = new ConcreteStrategy1();
    // 声明上下文对象
    Context context = new Context(strategy);
    // 执行封装后的方法
    context.doAnything();
  }
}

扩展策略枚举

public enum Calculator{
  // 加法运算
  ADD("+"){
    public int exec(int a,int b){
      return a+b;
    }
  }
  // 减法运算
  SUB("-"){
    public int exec(int a,int  b){
      return a-b;
    }
  };
  String value = "";
  private Calculator(String _value){
    this.value = _value;
  }
  public String getValue(){
    return this.value;
  }
  public abstract int exec(int a,int b);
}

场景类

public class Client{
  public static void main(Stringp[] args){
    int a = Integer.parseInt(args[0]);
    String symbol = args[1]; //符号
    int b = Integer.parseInt(args[2]]);
    System.out.println("输入的参数为:"+Arrays.toString(args));
    System.out.println("运行结果为:"+a+symbol+"="+Calculator.ADD.exec(a,b));
  }
}

适配器模式

定义:将一个类的接口变换成客户端所期待的另一种接口,从而是原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

模式中的各角色

  • Target目标角色:该角色定义把其他类转换为何种接口,也就是我们的期望接口。
  • Adaptee源角色:你想把谁转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象。
  • Adapter适配器角色:适配器模式的核心角色。

通用代码

目标角色:

public interface Target{
  // 目标角色有自己的方法
  public void request();
}

目标角色的实现类:

public void request(){
  System.out.println("if you need any help,pls call me");
}

源角色:

public class Adaptee{
  // 原有的业务逻辑
  public void request(){
    System.out.println("I'm kind of busy");
  }
}

适配器角色:

public class Adapter extends Adaptee implements Target{
  public void request(){
    super.doSomething();
  }
}

场景类:

public class Client{
  public static void main(Stirngp[] args){
    // 原有的业务逻辑
    Target target = new ConcreteTarget();
    target.request();
    // 现在增加了适配器角色后的业务逻辑
    Target target2 = new Adapter();
    target2.request();
  }
}

扩展:类适配器和对象适配器

迭代器模式

定义:它提供一种方法访问一个容器对象中各元素,而又不需暴露该对象的内部细节。Java开发中尽量不要自己写迭代器模式,使用Java提供Iterator一般能满足要求了

模式中各角色

  • Iterator抽象迭代器:抽象迭代器负责定义和遍历元素接口,而且基本上是固定有三个方法。first()获得第一个元素,next()访问下一个元素,isDone()是狗已经访问到底部(Java叫做hasNext()方法)
  • ConcreteIterator具体迭代器:具体迭代器角色要实现迭代器接口,完成容器元素的遍历。
  • Aggregate抽象容器:容器角色负责提供具体迭代器角色的接口,必然提供一个类似creteIterator()这样的方法,在Java中一般是Iterator()方法。
  • Concrete Aggregate具体容器:具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。

通用代码

抽象迭代器:

public interface Iterator{
  // 遍历到下一个元素
  public Object next();
  // 是否已经遍历到尾部
  public boolean hasNext();
  // 删除当前指向的元素
  public boolean remove();
}

具体迭代器

public class ConcreteIterator implements Iterator{
  private Vector vector = new Vector();
  // 定义当前游标
  public int cursor = 0;
  @SuppressWarnings("uncheked")
  public ConcreteIterator(Vector _vector){
    this.vector = _vector;
  }
  // 判断是否到达尾部
  public boolean hasNext(){
    if(this.cursor == this.vector.size()){
      return false;
    }else{
      return true;
    }
  }
  // 返回下一个元素
  public Object next(){
    Object result = null;
    if(this.hasNext()){
      result = this.vector.get(this.cursor++);
    }else{
      result = null;
    }
    return result;
  }
  // 删除当前元素
  public boolean remove(){
    this.vector.remove(this.cursor);
    return true;
  }
}

抽象容器:

public interface Aggregate{
  // 是容器必然有元素的增加
  public void add(Object object);
  // 减少元素
  public void remove(Object object);
  // 由迭代器来遍历所有的元素
  public Iterator iterator();
}

具体容器:

public class ConcreteAggregate implements Aggregate{
  // 容纳对象的容器
  private Vector  = new Vector();
  // 增加一个元素
  public void add(Object object){
    this.vector.add(object);
  }
  // 返回迭代器对象
  public Iterator iterator(){
    return new ConcreteIterator(this.vector);
  }
  // 删除一个元素
  public void remove(Object object){
    this.vector.remove(object);
  }
}

场景类:

public class Client{
  public static void main(String[] args){
    // 声明出容器
    Aggregate agg = new ConcreteAggregate();
    // 产生对象数据放进去
    agg.add("abc");
    agg.add("aaa");
    aaa.add("1234");
    // 遍历一下
    Iterator iterator = agg.iterator();
    while(iterator.hasNext()){
      System.out.println(iterator.next());
    }
  }
}

组合模式

定义:将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

模式中的各角色

  • Component抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。
  • Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。
  • Composite树枝结构:作用是组合树枝节点和叶子节点形成一个树形结构。

通用代码

抽象构件

public abstract class Component{
  // 个体和整体都具有
  public void doSomething(){
    // 填写业务逻辑
  }
}

树枝构件

public class Composite extends Component{
  // 构件容器
  private ArrayList<Component> componentArrayList = new ArrayList<Component>();
  // 增加一个叶子构件或树枝构件
  public void add (Component component){
    this.componentArrayList.add(component);
  }
  //删除一个叶子构件或树枝构件
  public void remove(Component component){
    this.componentArrayList.remove(component);
  }
  // 获得分支下的所有叶子构件和树枝构件
  public ArrayList<Component> getChildren(){
    return this.componentArrayList;
  }
}

树叶构件:

public class Leaf extends Component{
  /*
   *可以覆写父类方法
   *public void doSomething(){
   *
   *}
   */
}

场景类:

public class Client{
  public static void main(String[] args){
    // 创建一个根节点
    Composite root = new Composite();
    root.doSomething();
    // 创建一个树枝构件
    Composite branch = new Composite();
    // 创建一个叶子节点
    Leaf leaf = new Composite();
    // 建立整体
    root.add(branch);
    branch.add(leaf);
  }
  // 通过递归遍历树
  public static void display(Composite root){
    for(COmponent c:root.getChildren()){
      if(c instanceof Leaf){ // 叶子节点
        c.doSomething();
      }else{ // 树枝节点
        display((Composite)c);
      }
    }
  }
}

观察者模式

定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

模式中的角色

  • Subject被观察者:定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
  • Observer观察者:观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。
  • ConcreteSubject具体的被观察者:定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
  • ConcreteObserver具体的观察者:每个观察者在接收到消息后的处理反应是不同的,各个观察者有自己的处理逻辑。

通用代码

被观察者:

public abstract class Subject{
  // 定义一个观察者数组
  private Vector<Observer> obsVector = new Vector<Observer>();
  // 增加一个观察者
  public void addObsrver(Obsrver o){
    this.obsVector.add(o);
  }
  // 删除一个观察者
  public delObserver(Observer o){
    this.obsVector.remove(o);
  }
  // 通知所有观察者
  public void notifyObservers(){
    for(Observer o:this.obsVector){
      o.update();
    }
  }
}

具体被观察者:

public class ConcreteSubject extends Subject{
  // 具体的业务
  public void doSomething(){
    /*
     * doSomething
     */
     super.notifyObservers();
  }
}

观察者:

public interface Obsercer{
  // 更新方法
  public void update();
}

具体观察者:

public interface Observer{
  // 更新方法
  public void update();
}

具体观察者:

public class ConcreteObserver implements Observer{
  // 实现更新方法
  public void update(){
    System.out.println("接收到信息,并进行处理");
  }
}

场景类:

public class Client{
  public static void main(Stringp[] args){
    // 创建一个别观察者
    ConcreteSubject subject = new ConcreteSubject();
    // 定义一个观察者
    Observer obs = new ConcreteObserver();
    //观察者观察被观察者
    subject.addObserver(obs);
    // 被观察者开始活动了
    subject.doSomething();
  }
}

门面模式(外观模式)

定义:要求一个子系统的外部与其内部的通信必须通过与一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。

模式中的各角色

  • Facade门面角色:客户端可以调用这个角色的方法。此角色知晓子系统的所有功能和责任。一般情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就是说该角色没有实际的业务逻辑,只是一个委托类。
  • subsystem子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。子系统不知道门面的存在,对于子系统而言,门面仅仅是另外一个客户端而已。

通用代码

子系统:

public class ClassA{
  public void doSomethingA(){
    //业务逻辑
  }
}
public class ClassB{
  public void doSomethingB{
    //业务逻辑
  }
}
public class ClassC{
  public void doSomethingC{
    //业务逻辑
  }
}

门面对象:

public class Facade{
  // 被委托的对象
  private ClassA a = new ClassA();
  private ClassB b = new ClassB();
  private ClassC c = new ClassC();
  // 提供给外部访问的方法
  public void methodA(){
    this.a.doSomethingA();
  }

  public void methodB(){
    this.a.doSomethingB();
  }

  public void methodC(){
    this.a.doSomethingC();
  }
}

备忘录模式

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

模式中的各角色

  • Originator发起人角色:记录当前时刻的内部状态,负责定义哪些属于备份范围内的状态,负责创建和恢复备忘录数据。
  • Memento备忘录角色:负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
  • Caretaker备忘录管理员角色:对备忘录进行管理、保存和提供备忘录。

通用代码

发起人角色

public class Originator{
  // 内部状态
  private String state = "";

  public String getState(){
    return state;
  }
  public String setState(){
    this.state = state;
  }
  // 创建一个备忘录  
  public Memento createMemento(){
    return new Memento(this.state);
  }
  // 恢复一个备忘录
  publci void restoreMemento(Memento _memento){
    this.setState(_memento.getState());
  }
}

备忘录角色:

public class Memento{
  //发起人的内部状态
  private String state = "";
  // 构造函数传递参数
  public Memento(String _state){
    this.state = _state;
  }
  public String getState(){
    return state;
  }
  public setState(String state){
    this.state = state;
  }
}

备忘录管理员角色:

public class Caretaker{
  // 备忘录对象
  private Memento memento;
  public Memento getMemento(){
    return memento;
  }
  public void setMemento(Memento memento){
    this.memento = memento;
  }
}

场景类:

public class Client{
  public static void main(String[] args){
    // 定义发起人
    Originator originator = new Originator();
    // 定义出备忘录管理员
    Caretaker caretaker = new Caretaker();
    // 创建一个备忘录
    caretaker.setMemento(originator.createMemento());
    // 恢复一个备忘录
    originator.restoreMemento(caretaker.getMemento());
  }
}

访问者模式

定义:封装一些作用于某种数据及结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

模式中的各角色

  • Visitor抽象访问者:抽象类或接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的。
  • ConcreteVisitor具体访问者:它影响访问者访问到一个类后该怎么干,要做什么事情。
  • Element抽象元素:接口或者抽象类,声明接受哪一类访问者的访问,程序上是通过accept方法中的参数来定义的。
  • ConcreteElement具体元素:实现accept方法,通常是visitor.visit(this),基本上都形成了一种模式了。
  • ObjectStruture结构对象:元素产生着,一般容纳在多个不同类、不同接口的容器,如List、Set、Map等,在项目中,一般很少抽象出这个角色。

通用代码:

抽象元素:

public abstract class Element{
  // 定义业务逻辑
  public abstract void doSomething();
  //允许谁来访问
  public abstract void accept(IVisitor visitor);
}

具体元素:

public class ConcreteElement1 extends Element{
  // 完善业务逻辑
  public void doSomething(){
    // 业务逻辑
  }
  // 允许哪个访问者访问
  public void accept (IVisitor visitor){
    visitor.visitor(this);
  }
}
public class ConcreteElement2 extends Element{
  // 完善业务逻辑
  public void doSomething(){
    // 业务逻辑
  }
  // 允许哪个访问者访问
  public void accept (IVisitor visitor){
    visitor.visitor(this);
  }
}

抽象访问者:

public interface IVisitor{
  //可以访问哪些对象
  public void visit(ConcreteElement1 el1);
  public void visit(ConcreteElement2 el2);
}

具体访问者:

public class Visitor implements IVisitor{
  // 访问el1元素
  public void visit(ConcreteElement1 el1){
    el1.doSomething();
  }
  // 访问el2元素
  public void visit(ConcreteElement2 el2){
    el2.doSomething();
  }
}

结构对象:

public class ObjectStruture{
  // 对象生成器,这里通过一个工厂方法模式模拟
  public static Element creteElement(){
    Random rand = new Random();
    if(rand.nextInt(100)>50){
      return new ConcreteElement1();
    }else{
      return new ConcreteElement2();
    }
  }
}

场景类:

public class Client{
  public static void main(String[] args){
    for(int i=0;i<10;i++){
      // 获得元素对象
      Element el = ObjectStruture.createElement();
      // 接受访问者访问
      el.accept(new Visitor());
    }
  }
}

状态模式

定义:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。

模式中的各角色

  • State抽象状态角色:接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
  • ConcreteState具体状态角色:每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说。就是本状态下要做的事情,以及本状态如何过渡到其他状态。
  • Context环境角色:定义客户端需要的接口,并且负责具体状态的切换。

通用代码

抽象环境角色:

public abstract class State{
  // 定义一个环境角色,提供子类访问
  protected Context context;
  // 设置环境角色
  public void setContext(Context _context){
    this.context = _context;
  }
  // 行为1
  public abstract void handle1();
  // 行为2
  public abstract void handle2();
}

环境角色

public class ConcreteState1 extends State{
  @Override
  public void handle1(){
    // 本状态下必须处理的逻辑
  }
  @Override
  public void handle2(){
    // 设置当前状态为state2
    super.context.setCurrentState(Context.STATE2);
    // 过渡到state2状态,由Context实现
    super.context.handle2();
  }
}
public class ConcreteState1 extends State{
  @Override
  public void handle1(){
    // 设置当前状态为state1
    super.context.setCurrentState(Context.STATE1);
    // 过渡到state1状态,由Context实现
    super.context.handle1();
  }
  @Override
  public void handle2(){
    // 本状态下必须处理的逻辑
  }
}

具体环境角色:

public class Context{
  // 定义状态
  public final static State STATE1 = new ConcreteState1();
  public final static State STATE2 = new ConcreteState2();
  // 当前状态
  private State CurrentState;
  // 获得当前状态
  public State getCurrentState(){
    return CurrentState;
  }
  // 设置当前状态
  public void setCurrentState(State currentState){
    this.CurrentState = currentState;
    // 切换状态
    this.CurrentState.setContext(this);
    // 行为委托
    public void handle1(){
      this.CurrentState.handle1();
    }
    public void handle2(){
      this.CurrentState.handle2();
    }
  }
}

场景类:

public class Client{
  public static void main(Stringp[] args){
    // 定义环境角色
    Context context = new Context();
    // 初始化角色
    context.setCurrentState(new ConcurrentState1());
    // 行为执行
    context.handle1();
    context.handle2();
  }
}

解释器模式

定义:给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。较少用。

模式中的各角色

  • AbstractExpression抽象解释器:具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和Non-terminalExpression完成。
  • TerminalExpression终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的的终结符。
  • NonterminalExpression非终结符表达式
  • Context环境角色

通用代码

抽象表达式:

public abstract class Expression{
  // 每个表达式必须有一个解析任务
  public abstract Object interpreter(Context ctx);
}

终结符表达式:

public class TerminalExpression extends Expression{
  // 通常终结符表达式只有一个,但是又多个对象
  public Object interpreter(Context ctx){
    return null;
  }
}

非终结符表达式:

public class NonterminalExpression extends Expression{
  // 每个非终结符表达式都会对其他表达式产生依赖
  public NonterminalExpression(Expression... expression){
  }
  public Object interpreter(Context ctx){
    // 进行文法处理
    return null;
  }
}

客户类:

public class Client{
  public static void main(String[] args){
    Context ctx = new Context();
    // 通常定一个语法容器,容纳一个具体的表达式,通常为ListArray、LinkedList、Stack等类型
    Stack<Expression> stack = null;
    for(;;){
      // 进行语法判断,并产生递归调用
    }
    // 产生一个完整的语法树,由各个具体的语法分析进行解析
    Expression exp = stack.pop();
    // 具体元素进入场景
    exp.interpreter(ctx);
  }
}

享元模式

定义:使用共享对象可有效地支持大量的细粒度对象。
内部状态:内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境改变而改变。
外部状态:外部状态时对象得以依赖的一个标记,是随环境改变而改变的、不可以共享的状态。

模式中的角色

  • Flyweight抽象享元角色:它简单地说就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。
  • ConcreteFlyweight具体享元角色:具体的一个产品类,实现抽象角色定义单独业务。该角色中需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改变了内部抓过你太,同时修改了外部状态,这是绝对不允许的。
  • unsharedConcreteFlyweight不可共享的享元角色:不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。
  • FlyweightFactory享元工厂:职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方法。

通用代码

抽象享元角色:

public abstract class Flyweught{
  // 内部状态 
  private String intrinsic;
  // 外部状态
  protected final String Extrinsic;
  // 要求享元角色必须接受外部状态
  public Flyweight(String _Extrinsic){
    this.Extrinsic = _Extrinsic;
  }
  // 定义业务操作
  public abstract void operate();
  // 内部状态的getter/setter
  public String getIntrinsic(){
    return intrinsic;
  }
  public void setIntrinsic(String instrinsic){
    this.intrinsic = instrinsic;
  }
}

具体享元角色:

public class ConcreteFlyweight1 extends Flyweight{
  // 接受外部状态
  public ConcreteFlyweight1(String _Extinsic){
    super(_Extrinsic);
  }
  // 根据外部状态进行逻辑处理
  public void operate(){
    // 业务逻辑
  }
}
public class ConcreteFlyweight2 extends Flyweight{
  // 接受外部状态
  public ConcreteFlyweight2(String _Extinsic){
    super(_Extrinsic);
  }
  // 根据外部状态进行逻辑处理
  public void operate(){
    // 业务逻辑
  }
}

享元工厂:

public class FlyweightFactory{
  // 定义一个池容器
  private static HashMap<String,Flyweight> pool = new HashMap<String,Flyweight>();
  // 享元工厂
  public static Flyweight getFlyweight(String Extrinsic){
    // 需要返回的对象
    Flyweight flyweight = null;
    // 在池中没有该对象
    if(pool.containKey(Extrinsic)){
      flyweight = pool.get(Extrinsic);
    }else{
      // 根据外部状态创建享元对象
      flyweight = new ConcreteFlyweight1(Extrinsic);
      // 放置到池中
      pool.put(Extrinsic,flyweight);
    }
    return flyweight;
  }
}

桥梁模式

定义:也叫桥接模式。将抽象和实现解耦,使得连着可以独立地变化。

模式中的角色

  • Abstraction抽象化角色:它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类。
  • Implementor实现化角色:它是接口或者抽象类,定义角色必需的行为和属性。
  • RefinedAbstraction修正抽象化角色:它引用实现化角色对抽象化角色进行修正。
  • ConcreteImplementor具体实现化角色:它实现接口或抽象类定义的方法和属性。

通用代码

实现化角色:

public interface Implementor{
  // 基本方法
  public void doSomething();
  public void doAnything();
}

具体实现化角色:

public class ConcreteImplementor1 implements Implementor{
  public void doSomething(){
    // 业务逻辑
  }
  public void doAnything(){
    // 业务逻辑
  }
}
public class ConcreteImplementor2 implements Implementor{
  public void doSomething(){
    // 业务逻辑
  }
  public void doAnything(){
    // 业务逻辑
  }
}

抽象化角色:

public abstract class Abstraction{
  // 定义对实现化角色的引用
  private Implementor imp;
  // 约束子类必须实现该构造函数
  public Abstraction(Implementor _imp){
    this.imp = _imp;
  }
  // 自身的行为和属性
  public void request(){
    this.imp.doSomething();
  }
  // 获得实现化角色
  public Implementor getImp{
    return imp;
  }
}

具体抽象化角色:

public class RefinedAbstraction extends Abstraction{
  // 覆写构造函数
  public RefinedAbstraction(Implementor _imp){
    super(_imp);
  }
  // 修正父类行为
  @Override
  public void request(){
    /*
     *业务处理...
     */
    super.request();
    super.getImp().doAnything();
  }
  
}

场景类:

public class Client{
  public static void main(Stringp[] args){
    // 定义一个实现化角色
    Implementor imp = new ConcreteImplementor1();
    // 定义一个抽象化角色
    Abstraction abs = new RefinedAbstraction(imp);
    // 执行行文
    abs.request();
  }
}
posted @ 2024-01-27 23:20  yu*2  阅读(154)  评论(0)    收藏  举报