Java学习笔记之——设计模式

Java学习笔记之——设计模式

一 . 设计模式的六大基本原则

1、开闭原则(Open Close Principle)
对扩展开放,对修改关闭。在程序需要进行拓展的时候,在不修改原有的代码前提下改变其行为。

2、里氏代换原则(Liskov Substitution Principle)
任何基类可以出现的地方,子类一定可以出现。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现。

3、依赖倒转原则(Dependence Inversion Principle)
针对接口编程,依赖于抽象而不依赖于具体。就是对抽象进行编程,不要求对实现进行编程,降低模块之间的耦合度。

4、接口隔离原则(Interface Segregation Principle)
将不同的功能定义在不同的接口中来实现接口的隔离,避免其他类在依赖该接口时依赖其不需要的接口,减少接口之间依赖的冗余性和复杂性。

5、迪米特法则,又称最少知道原则(Demeter Principle)
一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)
尽量使用合成/聚合的方式,而不是使用继承。

二. 设计模式的类型

1.创建型模式

工厂模式(Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)
单例模式(Singleton Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)

2.结构型模式

适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)

3.行为型模式

责任链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
观察者模式(Observer Pattern)
状态模式(State Pattern)
策略模式(Strategy Pattern)
模板模式(Template Pattern)
访问者模式(Visitor Pattern)

二. 设计模式的具体实现

1.工厂模式(Factory Pattern)

在接口中定义创建对象的方法,将具体创建对象的过程在子类中实现,用户只需通过接口获取需要的对象即可,不用关注对象的具体创建过程。

public interface Shape {
	public void draw();
}
public class Circle implements Shape{
	@Override
	public void draw() {
		System.out.println("I am Circle");
	}
}
public class Square implements Shape{
	@Override
	public void draw() {
		System.out.println("I am Square");
	}
}
//定义图形工厂
public class ShapeFactory{
	public Shape getShape(String shapeType){
		if ("CIRCLE".equals(shapeType)) {
			return new Circle();
		}else if ("SQUARE".equals(shapeType)) {
			return new Square();
		}
		return null;
	}
}
//test
public static void main(String[] args) {
	ShapeFactory shapeFactory=new ShapeFactory();
	Shape shape= shapeFactory.getShape("CIRCLE");
	shape.draw();//I am Circle
}
2.抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式在工厂模式上添加了创建不同工厂的抽象接口,通过抽象接口创建不同的工厂对象,然后根据不同的工厂对象创建不同的对象。

public interface Shape {
	public void draw();
}
public class Circle implements Shape{
	@Override
	public void draw() {
		System.out.println("I am Circle");
	}
}
public class Square implements Shape{
	@Override
	public void draw() {
		System.out.println("I am Square");
	}
}
public interface Color {
   void fill();
}
public class Red implements Color {
   @Override
   public void fill() {
      System.out.println("I am Red");
   }
}
public class Blue implements Color {
   @Override
   public void fill() {
      System.out.println("I am Blue");
   }
}
//抽象工厂
public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape) ;
}
public class ShapeFactory extends AbstractFactory {

   @Override
   public Shape getShape(String shapeType){
     if ("CIRCLE".equals(shapeType)) {
			return new Circle();
		}else if ("SQUARE".equals(shapeType)) {
			return new Square();
		}
		return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}
public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {  
      if("RED".equals(color)){
         return new Red();
      } else if("BLUE".equalsIgnoreCase(color)){
         return new Blue();
      }
      return null;
   }
}
//创建一个工厂生成器
public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if("SHAPE".equals(choice)){
         return new ShapeFactory();
      } else if("COLOR".equals(choice)){
         return new ColorFactory();
      }
      return null;
   }
}
//test
public static void main(String[] args) {

      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
      Shape shape = shapeFactory.getShape("CIRCLE");
      shape.draw();
      
      //获取颜色工厂
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
      Color color = colorFactory.getColor("RED");
      color.fill();
   }
3.单例模式(Singleton Pattern)

单例模式实例化对象的机制分两种:懒汉式、饿汉式。懒汉式就是在调用的时候才实例化对象,而饿汉模式是在加载类的时候就已经实例化对象了。

//懒汉式
public class Singleton {

	private static Singleton singleton=null;

    private Singleton(){}
    
    public static Singleton getInstance(){
            if (singleton ==null){
                synchronized (Singleton.class){
                    if (singleton ==null){
                        singleton= new Singleton();
                    }
                }
            }
       return singleton;
    }
}
//饿汉式
public class Singleton {

	private static final Singleton singleton=new Singleton();
	
    private Singleton(){}
    
    public static Singleton getInstance(){
       return singleton;
    }
}
4.建造者模式(Builder Pattern)

建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。建造者模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成

关键点:
1.产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个部件。定义了该复杂对象的结构和内部表示。
2.抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象接口。
3.具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
4.指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,定义复杂产品各个部件的装配流程。

public 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(){
        //显示产品的特性
    }
}
public abstract class Builder{
    //创建产品对象
    protected Product product=new Product();
    
    public abstract void buildPartA();
    
    public abstract void buildPartB();
    
    public abstract void buildPartC();
    //返回产品对象
    public Product getResult(){
        return product;
    }
}
public class ConcreteBuilder extends Builder{

    public void buildPartA() {
        product.setPartA("建造 PartA");
    }
    
    public void buildPartB(){
        product.setPartA("建造 PartB");
    }
    
    public void buildPartC(){
        product.setPartA("建造 PartC");
    }
}
public class Director{

    private Builder builder;
    
    public Director(Builder builder){
        this.builder=builder;
    }
    
    //产品构建与组装方法
    public Product construct(){
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}
	//test
	public static void main(String[] args){
        Builder builder=new ConcreteBuilder();
        Director director=new Director(builder);
        Product product=director.construct();
        product.show();
    }
5.原型模式(Prototype Pattern)

原型模式是指调用原型实例的Clone方法用于创建重复的对象。

关键点:
1.继承 Cloneable,重写 clone()方法。

public abstract class Shape implements Cloneable {
   
   private String id;
   
   protected String type;
   
   abstract void draw();
   
   public String getType(){
      return type;
   }
   
   public String getId() {
      return id;
   }
   
   public void setId(String id) {
      this.id = id;
   }
   
   public Object clone() {
      Object clone = null;
      try {
         clone = super.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }
      return clone;
   }
}
public class Square extends Shape {
 
   public Square(){
     type = "Square";
   }
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
public class Circle extends Shape {
 
   public Circle(){
     type = "Circle";
   }
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}
public class ShapeCache {
    
   private static Hashtable<String, Shape> shapeMap 
      = new Hashtable<String, Shape>();
 
   public static Shape getShape(String shapeId) {
      Shape cachedShape = shapeMap.get(shapeId);
      return (Shape) cachedShape.clone();
   }
 
   // 对每种形状都运行数据库查询,并创建该形状
   // shapeMap.put(shapeKey, shape);
   // 例如,我们要添加三种形状
   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);
 
      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);
   }
}
public static void main(String[] args) {
      ShapeCache.loadCache();
      
      Shape clonedShape1 = (Shape) ShapeCache.getShape("1");
      System.out.println("Shape : " + clonedShape1.getType());        
 
      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType()); 
   }
6.适配器模式(Adapter Pattern)

适配器模式是作为两个不兼容的接口之间的桥梁,将一个类的接口转换成用户期望的另一个接口,使得两个或多个原本不兼容的接口可以基于适配器类一起工作。

关键点:
1.目标(Target)接口:当前系统业务所期待的接口(新的接口),它可以是抽象类或接口。
2.适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
3.适配器(Adapter)类:通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

//目标接口
public interface Target{
    public void request();
}
//适配者接口
public class Adaptee{
    public void specificRequest(){ 
        System.out.println("适配者中的业务代码被调用!");
    }
}
//类适配器类
class ClassAdapter extends Adaptee implements Target{
    public void request(){
        specificRequest();
    }
}
	//test
	public static void main(String[] args){
        Target target = new ClassAdapter();
        target.request();
    }
7.桥接模式(Bridge Pattern)

将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

关键点:
1.抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
2.扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
3.实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
4.具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

public abstract class Shape {
    Color color;

    public void setColor(Color color) {
        this.color = color;
    }

    public abstract void draw();
}
public class Circle extends Shape{

    public void draw() {
        color.bepaint("圆");
    }
}
public class Rectangle extends Shape{

    public void draw() {
        color.bepaint("长方形");
    }

}
public interface Color {
    void bepaint(String shape);
}
public class White implements Color{

    public void bepaint(String shape) {
        System.out.println("白色的" + shape);
    }

}
public class Black implements Color{

    public void bepaint(String shape) {
        System.out.println("黑色的" + shape);
    }
}
public static void main(String[] args) {
        Color white = new White();
        Shape square = new Circle();
        square.setColor(white);
        square.draw();

        Shape rectange = new Rectangle();
        rectange.setColor(white);
        rectange.draw();

        Color black=new Black();
        Shape square2 = new Circle();
        square2.setColor(black);
        square2.draw();

        Shape rectange2 = new Rectangle();
        rectange2.setColor(black);
        rectange2.draw();
    }
8.组合模式(Composite Pattern)

组合模式又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性

关键点:
1.抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。
2.树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中声明的公共接口。
3.树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

//抽象构件
public interface Component
{
    void add(Component c);
    void remove(Component c);
    Component getChild(int i);
    void operation();
}
//树叶构件
public class Leaf implements Component
{
    private String name;
    public Leaf(String name)
    {
        this.name=name;
    }
    public void add(Component c){ }           
    public void remove(Component c){ }   
    public Component getChild(int i)
    {
        return null;
    }   
    public void operation()
    {
        System.out.println("树叶"+name+":被访问!"); 
    }
}
//树枝构件
class Composite implements Component
{
    private ArrayList<Component> children=new ArrayList<Component>();   
    public void add(Component c)
    {
        children.add(c);
    }   
    public void remove(Component c)
    {
        children.remove(c);
    }   
    public Component getChild(int i)
    {
        return children.get(i);
    }   
    public void operation()
    {
        for(Object obj:children)
        {
            ((Component)obj).operation();
        }
    }    
}
 public static void main(String[] args) {
        Component c0=new Composite(); 
        Component c1=new Composite(); 
        Component leaf1=new Leaf("1"); 
        Component leaf2=new Leaf("2"); 
        Component leaf3=new Leaf("3");          
        c0.add(leaf1); 
        c0.add(c1);
        c1.add(leaf2); 
        c1.add(leaf3);          
        c0.operation(); 
}
9.装饰器模式(Decorator Pattern)

装饰器模式是指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

关键点:
1.抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
2.具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
3.抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
4.具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

//抽象构件角色
public interface  Component {
    
    public void operation();
    
}
//具体构件角色
public class ConcreteComponent implements Component {
    public void operation() {
        System.out.println("调用具体构件角色的方法operation()");
    }
}
//抽象装饰角色
public class Decorator implements Component {
    
    private Component component;
    
    public Decorator(Component component) {
        this.component=component;
    }
    
    public void operation() {
        component.operation();
    }
}
//具体装饰角色
public class ConcreteDecorator extends Decorator {
    
    public ConcreteDecorator(Component component) {
        super(component);
    }
    
    public void operation() {
        super.operation();
        addedFunction();
    }
    
    public void addedFunction() {
        System.out.println("为具体构件角色增加额外的功能addedFunction()");
    }
}
public static void main(String[] args) {
        Component p=new ConcreteComponent();
        p.operation();
        
        System.out.println("---------------------------------");
        
        Component d=new ConcreteDecorator(p);
        d.operation();
}
10.外观模式(Facade Pattern)

外观模式是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

关键点:
1.外观(Facade)角色:为多个子系统对外提供一个共同的接口。
2.子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
3.客户(Client)角色:通过一个外观角色访问各个子系统的功能。

//外观角色
public class Facade {
    private SubSystem01 obj1=new SubSystem01();
    private SubSystem02 obj2=new SubSystem02();
    
    public void method() {
        obj1.method1();
        obj2.method2();
    }
}
//子系统角色
public class SubSystem01 {
    
    public  void method1() {
        System.out.println("子系统01的method1()被调用!");
    }
}
//子系统角色
public class SubSystem02 {
    
    public  void method2() {
        System.out.println("子系统02的method2()被调用!");
    }
}
public static void main(String[] args) {
        Facade f=new Facade();
        f.method();
}
11.享元模式(Flyweight Pattern)

享元模式是运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

关键点:
1.用 HashMap 存储这些对象
2.抽象享元角色(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
3.具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
4.非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
5.享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

//抽象享元角色
public interface Flyweight {
  public void operation(UnsharedConcreteFlyweight state);
}
//具体享元角色
public class ConcreteFlyweight implements Flyweight {
    
    private String key;
    
    ConcreteFlyweight(String key) {
        this.key=key;
        System.out.println("具体享元"+key+"被创建!");
    }
    
    public void operation(UnsharedConcreteFlyweight outState) {
        System.out.print("具体享元"+key+"被调用,");
        System.out.println("非享元信息是:"+outState.getInfo());
    }
}
//享元工厂角色
public class FlyweightFactory {
    
    private HashMap<String, Flyweight> flyweights=new HashMap<String, Flyweight>();
    
    public Flyweight getFlyweight(String key) {
        Flyweight flyweight=(Flyweight)flyweights.get(key);
        if(flyweight!=null) {
            System.out.println("具体享元"+key+"已经存在,被成功获取!");
        } else {
            flyweight=new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
        }
        return flyweight;
    }
}
public static void main(String[] args) {
    FlyweightFactory factory=new FlyweightFactory();
    Flyweight f01=factory.getFlyweight("a");
    Flyweight f02=factory.getFlyweight("a");
    Flyweight f03=factory.getFlyweight("a");
    Flyweight f11=factory.getFlyweight("b");
    Flyweight f12=factory.getFlyweight("b");
    f01.operation(new UnsharedConcreteFlyweight("第1次调用a。"));
    f02.operation(new UnsharedConcreteFlyweight("第2次调用a。"));
    f03.operation(new UnsharedConcreteFlyweight("第3次调用a。"));
    f11.operation(new UnsharedConcreteFlyweight("第1次调用b。"));
    f12.operation(new UnsharedConcreteFlyweight("第2次调用b。"));
}
12.代理模式(Proxy Pattern)

访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

关键点:
1.抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
2.真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
3.代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能

public interface Subject {
    void request();
}
public class RealSubject implements Subject {
    public void request() {
        System.out.println("实际方法...");
    }
}
public class Proxy implements Subject {

    private RealSubject realSubject;

    public void request() {
        if (realSubject==null) {
            realSubject=new RealSubject();
        }
        realSubject.request();
    }

}
public static void main(String[] args) {
    Proxy proxy=new Proxy();
    proxy.request();
}
13.责任链模式(Chain of Responsibility Pattern)

为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

关键点:
1.抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
2.具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
3.客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

public abstract class Handler {
    
    private Handler next;
    
    public void setNext(Handler next) {
        this.next=next;
    }
    
    public Handler getNext() {
        return next;
    }
    //处理请求的方法
    public abstract void handleRequest(String request);
    
}
public class ConcreteHandler1 extends Handler {

    public void handleRequest(String request) {
        if (request.equals("one")) {
            System.out.println("具体处理者1负责处理该请求!");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(request);
            } else {
                System.out.println("没有人处理该请求!");
            }
        }
    }
}
public class ConcreteHandler2 extends Handler {

    public void handleRequest(String request) {
        if (request.equals("two")) {
            System.out.println("具体处理者2负责处理该请求!");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(request);
            } else {
                System.out.println("没有人处理该请求!");
            }
        }
    }
}
public static void main(String[] args) {
    //组装责任链 
    Handler handler1 = new ConcreteHandler1();
    Handler handler2 = new ConcreteHandler2();
    handler1.setNext(handler2);
    //提交请求 
    handler1.handleRequest("two");
}
14.命令模式(Command Pattern)

将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

关键点:
1.抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
2.具体命令角色(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
3.实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
4.调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

//抽象命令
public interface Command {
    abstract void execute();
}
//具体命令
public class ConcreteCommand implements Command {
    
    private Receiver receiver;
    
    ConcreteCommand() {
        receiver=new Receiver();
    }
    
    public void execute() {
        receiver.action();
    }
}
//接收者
public class Receiver {
    public void action() {
        System.out.println("接收者的action()方法被调用...");
    }
}
//调用者
public class Invoker {

    private Command command;

    public Invoker(Command command) {
        this.command=command;
    }

    public void setCommand(Command command) {
        this.command=command;
    }

    public void call() {
        System.out.println("调用者执行命令command...");
        command.execute();
    }
}
public static void main(String[] args) {
    Command cmd=new ConcreteCommand();
    Invoker ir=new Invoker(cmd);
    System.out.println("客户访问调用者的call()方法...");
    ir.call();
}
15.解释器模式(Interpreter Pattern)

给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。

关键点:
1.抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
2.终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
3.非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
4.环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
5.客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

public interface Expression {
    public boolean interpret(String info);
}
public class TerminalExpression implements Expression {

    private Set<String> set= new HashSet<String>();
    
    public TerminalExpression(String[] data) {
        for(int i=0;i<data.length;i++)set.add(data[i]);
    }
    
    public boolean interpret(String info) {
        if(set.contains(info)) {
            return true;
        }
        return false;
    }
}
public class AndExpression implements Expression {
    
    private Expression city=null;
    private Expression person=null;
    
    public AndExpression(Expression city,Expression person) {
        this.city=city;
        this.person=person;
    }
    
    public boolean interpret(String info) {
        String s[]=info.split("的");
        return city.interpret(s[0])&&person.interpret(s[1]);
    }
}
public class Context {
    
    private String[] citys={"韶关","广州"};
    private String[] persons={"老人","妇女","儿童"};
    private Expression cityPerson;
    
    public Context() {
        Expression city=new TerminalExpression(citys);
        Expression person=new TerminalExpression(persons);
        cityPerson=new AndExpression(city,person);
    }
    
    public void freeRide(String info) {
        boolean ok=cityPerson.interpret(info);
        if(ok) System.out.println("您是"+info+",您本次乘车免费!");
        else System.out.println(info+",您不是免费人员,本次乘车扣费2元!");
    }
}
public static void main(String[] args){
        Context bus=new Context();
        bus.freeRide("韶关的老人");
        bus.freeRide("韶关的年轻人");
        bus.freeRide("广州的妇女");
        bus.freeRide("广州的儿童");
        bus.freeRide("山东的儿童");
}
16.中介者模式(Mediator Pattern)

定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。

关键点:
1.抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
2.具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
3.抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
4.具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

//抽象中介者
public abstract class Mediator{
    public abstract void register(Colleague colleague);
    public abstract void relay(Colleague cl); 
}
public class ConcreteMediator extends Mediator{

    private List<Colleague> colleagues=new ArrayList<Colleague();
    
    public void register(Colleague colleague){
        if(!colleagues.contains(colleague)){
            colleagues.add(colleague);
            colleague.setMedium(this);
        }
    }
    
    public void relay(Colleague cl){
        for(Colleague ob:colleagues){
            if(!ob.equals(cl)){
                ((Colleague)ob).receive();
            }   
        }
    }
}
//抽象同事类
public abstract class Colleague{

    protected Mediator mediator;
    
    public void setMedium(Mediator mediator){
        this.mediator=mediator;
    }   
    
    public abstract void receive();   
    
    public abstract void send();
}
public class ConcreteColleague1 extends Colleague{
    public void receive(){
        System.out.println("具体同事类1收到请求。");
    }   
    
    public void send(){
        System.out.println("具体同事类1发出请求。");
        mediator.relay(this); //请中介者转发
    }
}
public class ConcreteColleague2 extends Colleague{
    public void receive(){
        System.out.println("具体同事类2收到请求。");
    }   
    
    public void send(){
        System.out.println("具体同事类2发出请求。");
        mediator.relay(this); //请中介者转发
    }
}
public static void main(String[] args){
        Mediator md=new ConcreteMediator();
        Colleague c1,c2;
        c1=new ConcreteColleague1();
        c2=new ConcreteColleague2();
        md.register(c1);
        md.register(c2);
        c1.send();
        System.out.println("-------------");
        c2.send();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值