设计模式学习(四) 行为型 -2- 观察者 备忘录 访问者 状态 解释器

这一篇写剩下五个行为型设计模式:

   观察者模式、备忘录模式、访问者模式、状态模式、解释器模式

#观察者模式(Observer Pattern) Define a one-to-many dependency between objects so that when one object changes state,all its dependents are notofied and updated automatically.

  也称发布订阅模式。对象间存在一对多关系时、当一个对象改变状态、所有依赖他的对象会得到通知并自动更新。

  优点:观察者和被观察者抽象耦合。观察者是一个集合、容易扩展。

  缺点:如果观察者过多会花费很多时间 如观察者和观察者对象具有循环依赖会导致系统崩溃。观察者只知道发生了变化但不知道是如何变化的。

  适用:一对多关系

  四个角色:

    抽象主题(Subject)角色:被观察者 可添加删除观察者

    抽象观察者(Observer)角色:观察者接口

    具体主题(Concrete Subject)角色:具体被观察者、需要发出通知

    具体观察者(Concrete Observer)角色:实现抽象观察者接口

 

 

抽象主题:

public interface Subject {

    void addObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyObserver();// 通知

}

抽象观察者:

// 抽象观察者
public interface Observer {

    void print();

}

具体主题:

public class ISubject implements Subject {

    private List<Observer> list = new ArrayList<Observer>();

    public void addObserver(Observer observer) {
        list.add(observer);
    }

    public void removeObserver(Observer observer) {
        list.remove(observer);
    }

    public void notifyObserver() {
        for (Observer o : list) {
            o.print();
        }
    }

    // 业务方法
    public void change() {
        this.notifyObserver();
    }

}

具体观察者:

public class IObserver implements Observer{

    public void print() {
        System.out.println("IObserver1 收到通知!");
    }

}

测试:

#备忘录模式(Memento Pattern)  Without violating encapsulation,capture and externalize an object's internal state sothat the object can be restored to this state later.

   快照(Snapshot)模式或Token模式。在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。以便在适当的时侯恢复到原先保存的状态。比如取消。

  优点:提供一个可恢复的机制 缺点:消耗资源

  三个角色:

    发起人(Originator)角色:定义哪些属于备份范围的状态

    备忘录(Memento)角色:负责存储

    负责人(Caretaker)角色:管理备忘录

 

 

发起人:

// 发起人
public class Originator {
    private String state;
    // 创建备忘录
    public Memento createMemento(){
        return new Memento(this.state);
    }

    public void restoreMemento(Memento memento){
        this.setState(memento.getState());
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

备忘录:

// 备忘录
public class Memento {

    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public void 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;
    }

}

测试:

 

 #访问者模式(Visitor Pattern)  Represent an operation to be performed on the elements of an object structure. Visitorlets you define a new operation without changing the classes of the elements on whichit operates.

  使用一个访问者类,改变了元素类的执行算法。

  优点:符合单一原则、优秀的可扩展性 新的操作仅需要增加新的访问者、关的行为集中到一个访问者对象中,而不是分散到一个个元素类中

  缺点:违背了依赖倒置原则。违反了迪米特原则。新增元素困难。

  五个角色:

    抽象访问者(Visitor)角色:定义访问者可以访问哪些元素。 指定客户可以访问那些东西

    具体访问者(Concrete Visitor)角色:各个访问操作 :客户

    抽象元素(Element)角色:东西

    具体元素(Concrete Element)角色:蔬菜 水果

    结构对象(Object Structure)角色:可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素

 

 

 抽象访问者:客户接口

// 抽象访问者
public interface Visitor {
    // 可访问的对象
    void visit(Fruit fruit);

    void visit(Vegetable vegetable);

}

具体访问者:具体客户

1:

// 具体访问者
public class IVisitor implements Visitor{

    public void visit(Fruit fruit) {
        System.out.println("水果:"+fruit.name);
    }

    public void visit(Vegetable vegetable) {
        System.out.println("蔬菜:"+vegetable.name);
    }
}

2:

public class IVisitor2 implements Visitor {
    public void visit(Fruit fruit) {
        System.out.println(fruit.name+"多少钱?");
    }

    public void visit(Vegetable vegetable) {
        System.out.println(vegetable.name+"怎么卖?");
    }
}

抽象元素:

public interface Element {

    void accept(Visitor visitor);

}

具体元素:水果 蔬菜

public class Fruit implements Element {

    public String name;

    public Fruit(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

}

 

public class Vegetable implements Element {

    public String name;

    public Vegetable(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

结构对象:购物车

public class ShoppingCart {
    List<Element> list = new ArrayList<Element>();

    public ShoppingCart() {
        list.add(new Fruit("苹果"));
        list.add(new Fruit("橙子"));
        list.add(new Vegetable("胡萝卜"));
        list.add(new Vegetable("白菜"));
    }

    public void print(Visitor visitor){
        for(Element e:list){
            e.accept(visitor);
        }
    }
}

测试:

 

#状态模式(State Pattern) Allow an object to alter its behavior when its internal state changes. The object willappear to change its class.

  允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类

  三个角色:

    抽象状态(State)角色:封装环境对象的一个特定状态所对应的行为

    具体状态(Concrete State)角色:该角色实现环境的一个状态所对应的行为

    环境(Context)角色:该角色定义客户端需要的接口,并负责具体状态的切换。它会保留一个具体状态类的实例,该实例给出环境对象的现有状态。

 

 

 

 抽象状态:

public interface State {
    
    void onClick(Button btn);

}

具体状态:

1:

public class StartState implements State {

    public void onClick(Button btn) {
        System.out.println("StartState");
        btn.setState(this);
    }

    @Override
    public String toString() {
        return "StartState{}";
    }
}

2:

public class StopState implements State {
    public void onClick(Button btn) {
        System.out.println("StopState");
        btn.setState(this);
    }

    @Override
    public String toString() {
        return "StopState{}";
    }
}

环境:

// 环境
public class Button {
    private State state;

    // get set
    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

}

测试:

 

#解释器模式(Interpreter Pattern) Given a language, define a representation for its grammar along with an interpreterthat uses the representation to interpret sentences in the language.

   给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。  

  五个角色:

    抽象表达式(Abstract Expression)角色:

    终结符表达式(Terminal Expression)角色:

    非终结符表达式(Nonterminal Expression)角色:

    环境(Context)角色:全局信息

    客户端(Client)角色:调用

 

 

抽象表达式:

public interface Expression {
    boolean interpret(String context);
}

 

public class IExpression implements Expression {

    private String data;

    public IExpression(String data) {
        this.data = data;
    }

    public boolean interpret(String context) {
        if(context.contains(data)){
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        return "IExpression{" +
                "data='" + data + '\'' +
                '}';
    }
}

 

public class OrExpression implements Expression {
    private Expression e1 = null;
    private Expression e2 = null;

    public OrExpression(Expression e1, Expression e2) {
        this.e1 = e1;
        this.e2 = e2;
    }

    public boolean interpret(String context) {
        return e1.interpret(context) || e2.interpret(context);
    }
}

 

public class AndExpression implements Expression {
    private Expression e1 = null;
    private Expression e2 = null;

    public AndExpression(Expression e1, Expression e2) {
        this.e1 = e1;
        this.e2 = e2;
    }

    public boolean interpret(String context) {
        return e1.interpret(context) && e2.interpret(context);
    }
}

环境:

public class Context {

    //规则:Robert true John true 
    public static Expression getMaleExpression(){
        Expression robert = new IExpression("Robert");
        Expression john = new IExpression("John");
        return new OrExpression(robert, john);
    }

    //规则:Julie Married true
    public static Expression getMarriedWomanExpression(){
        Expression julie = new IExpression("Julie");
        Expression married = new IExpression("Married");
        return new AndExpression(julie, married);
    }

}

测试:

 

 总结:

观察者模式 :对象间存在一对多关系时、当一个对象改变状态、所有依赖他的对象会得到通知并自动更新。

备忘录模式 :在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。以便在适当的时侯恢复到原先保存的状态。

访问者模式 :使用一个访问者类,改变了元素类的执行算法。

状态模式:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类

解释器模式:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

 

 

@

 

posted @ 2020-04-30 17:10  DarGi  阅读(181)  评论(0编辑  收藏  举报