Java经典23种设计模式之行为型模式(三)

本文接着介绍11种行为型模式里的备忘录模式、观察者模式、状态模式。

一、备忘录模式

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

1.Memento 备忘录存储原发器对象的内部状态,这个类就是要存储的对象的状态。状态需要多少个变量,在Memento里就写多少个变量。

public class Memento {

private String state;

public Meme*to(String state) {
        this.state = state;
    }

public String getState() {
        *eturn state;
    }

public void setSt*te(String state) {
        this.state = state;
    }

}

2.Originator原发器创建一个备忘录,用以记录当前时刻*的内部状态。使用备忘录恢复内部状态.

public class Originator {

private String state;

public String getState() {
        return state;
    }

public void setState(String state) {
        this.state = state;
    }
    
    *ublic Memento createMemento() {
        return new Memento(state);
    }
    
    p*blic void setMemento(Memento meme*to) {
        state = memento.ge*State();
    }
    
    p*blic void showState(){
        System.out.println(state);
    }
}

3.Caretaker 负责保存好备忘录。不能对备忘录的内*进行操作或检查。

public class Caretaker {
    
    p*ivate Memento memento;
    
    public Memento getMemento(){
        return this.memento;
    }
    
    public void setMemento(Memento memento){
        this.memento = memento;
    }
}

测试代码:

public class Test {
 
    public static void main(String[] args) {
        Originator org = *ew Originator();
        org*setState("开会中");
        
        C*retaker ctk = new Ca*etaker();
        ctk.setMemento(org.createMemento());//将数据封装在Caretaker
        
        or*.setState("睡觉中");
        org.sh*wState();*/显示
        
        org.setMemento(ctk.getMemento());//将数据重新导入
        or*.showState();
    }
}

适用性:

1.必须*存一个对象在某一个时刻的(部分)状态,这样以后需要时它才能恢复到先前的状态。
    2.如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。

参考链接:http://blog.sina.com.cn/s/blog_3d43347c0100bkm1.html

二、观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式用途很多。

1.Subject(目标) 也就是负责管理属于他的观察者,比如一个排长十个手下。这个排长就是subject.提供注册和删除观察者对象的接口。

public abstract class Citizen {
    
    List po*s;
    
    String help = "normal";
    
    public void setHelp(String help) {
        this.help = *elp;
    }
    
    public String getHelp() {
        return this.help;
    }
    
    abstract void sendMessage(String help);

public void setPolicemen() {
        t*is.pols = new ArrayList();
    }
    
    public void register(*oliceman pol) {
        this.pols.add(pol);
    }

public void unRegister(Policeman pol) {
        this.pols.remove(pol);
    }
}

2.Obser*er(观察者)为那些在目标发生改变时需获得*知的对象定义一个更新*口。

public interface Policeman {

void action(Citizen ci);
}

3.ConcreteSubject(具体目标) 将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。

public class Hua*gPuCitizen extends Citiz*n {
 
    public HuangPuCitizen(P*liceman pol) {
        setPolicemen();
        register*pol);
    }
    
    public void sendMessage(String help) {
        setHelp(h*lp);
        for(int i = 0; i < pols.size(); i++) {
            Policeman pol = pols.get(i);
            //通知警察行动
            pol.action(this);
        }
    }
}

public class TianHeCitizen extends Citizen {

public TianHeCitizen(Policeman pol) {
        setPolicemen();
        re*ister(pol);
    }
    
    public void sendM*ssage(Str*ng help) {
        setHelp(help);
        for (i*t i = 0; i < pols.size(); i++) {
            Policeman pol = pols.get(i);
            //通知警察行动
            pol.action(this);
        }
    }
}

4.ConcreteObserver(具体观察者)维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口*使自身状态与目标的状态保持一致.

public clas* HuangPuPoliceman implements Pol*ceman {

public void action(Citizen ci) {
        String help = ci.getHelp();
        if (help.equals("normal")) {
            System.o*t.println("一切正常, 不用出动");
        }
        if (help.*quals("unnormal")) *
            System.out.println("有犯罪行为, 黄埔警察出动!");
        }
    }
}

public c*ass TianHePoliceman implements Policem*n {

public void action(Citizen ci) {
        String help = *i.getHelp();
        if (help.equals("*ormal")) {
            System.out.println("一切正常, 不用出动");
        *
        if (help.equals("unnormal")) {
            System.out.println("有犯罪行为, 天河警察出动!");
        }
    }
}

测试代码:

public class Test{

public st*tic void main(String[] args) {
        Policeman thPol = new TianHePoliceman();
        Pol*ceman hpPol = new HuangPuPoliceman();
        
        Ci*izen citizen = new HuangPuCitizen(hpPol);
        citizen.sendMessage("unnormal");
        citizen.sendMessage("normal");
        
        System.out.println("===========");
        
        citizen = new TianH*Citizen(thPol);
        citizen.sendMessage("normal");
        citi*en.sendMessage("unnormal");
    }
}

有犯罪行为, 黄埔警察出动!
一切正常, 不用出动
======*====
一切正常, 不用出动
有犯罪行为, 天河警察出动!

适用性:

1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。
      将这二者封装*独立的对象中以使它们可以各自独立地改变和复用。
    2.当对一个对象的改变需要同时改变其它对象,而不知道具体*多少对象有待改变。
    3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。

观察者模式极其重要,更多可参考:http://www.iteye.com/topic/102068/

三、状态模式(State Pattern)

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

一个简单的例子参见链接:http://www.cnblogs.com/BenWong/archive/2012/12/12/2813982.html

下面上个复杂的例子:

1.Context定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。

pu*lic class Context {

private Weather weather;

public voi* setWeather(Weather weather) {
        this.*eather = weather;
    }

pu*lic Weather getWeather() {
        return this.weather;
    }

public String weatherMessage() {
        return w*ather.getWeather();
    }
}

2.State定义一个接口以封装与Context的一个特定状态相关的行为。

public interface Weath*r {

String getWeather();
}

3.ConcreteStatesubclasses每一子类实现一个与Context的一个状态*关的行为。

public class Rain implements Weather {

public Stri*g getWeather() {
        return "下雨";
    }
*

public class Sunshine implements Weather {

public Str*ng getWeather() {
        return "阳光";
    }
}

测试代码:

public class Test{

public static void main(String[] args) {
        Context ctx1 = new Context();
        ctx1.setWeather(new Sunshine());
        System.out.println(*tx1.weatherMessage());

System.*ut.println("===============");

Context ctx2 = new Context();
        ctx2.setWeather(new Rain());
        S*stem.out.println(ctx2.weatherMessage());
    }
}
result

阳光
===============
下雨

适用性:

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改*它的行为。
2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

参考链接:http://dev.yesky.com/438/2164938.shtml

Java经典23种设计模式之行为型模式(三),布布扣,bubuko.com

时间: 2024-10-18 10:22:20

Java经典23种设计模式之行为型模式(三)的相关文章

Java经典23种设计模式之行为型模式(一)

行为型设计模式有11种,分别是Chain of Responsibility ( 责任链模式 ).Command ( 命令模式 ).Interpreter ( 解释器模式 ) .Iterator ( 迭代器模式 ).Mediator ( 中介者模式 ) .Memento ( 备忘录模式 ) .Observer ( 观察者模式 ).State ( 状态模式 ) .Strategy ( 策略模式 ).TemplateMethod ( 模板方法 ).Visitor ( 访问者模式 ),本文介绍这11种

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

Java经典23种设计模式之行为型模式(二)

本文接着介绍行为型模式里的解释器模式.迭代器模式.中介者模式. 一.解释器模式Interpret 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言的中的句子. 1.AbstractExpression(抽象表达式) 声明一个抽象的解释操作,这个接口为抽象语法树中全部的节点所共享. public abstract class Expression {    abstract void interpret(Context ctx);} 2.Expression

Java经典23种设计模式之行为型模式(四)

本文介绍11种行为型设计模式里的策略模式.模板方法.访问者模式. 一.策略模式 定义一系列的算法,把它们每个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 1.Strategy定义所有支持的算法的公共接口.Context使用这个接口来调用某ConcreteStrategy定义的算法. public abstract class Strategy {    public abstract void method();} 2.ConcreteStrategy以Strate

Java经典23种设计模式之结构型模式(一)

结构型模式包括7种:适配器模式.桥接模式.组合模式.装饰模式.外观模式.享元模式.代理模式. 本文主要介绍适配器模式和桥接模式. 一.适配器模式(Adapter) 适配器模式其实很简单,就像手机充电器一样,手机需要5V的,而插座出来是220V.因此需要充电器变压就ok.再比如,一个之会说汉语的和一个只会说英语的无法沟通,那就中间请个翻译.所有的交流通过翻译,翻译翻给会说英语的,就能完成一次单项交流的.链接1 中的例子非常生动形象了.总结一下,无非就是有个通用的接口(称为Target),如果一切顺

Java经典23种设计模式之结构型模式(二)

接上篇,本文介绍结构型模式里的组合模式.装饰模式.外观模式. 一.组合模式(Composite) 组合模式:将对象组合成树形结构,表示"部分--整体"的层次结构.最终达到单个对象和组合对象的使用具有一致性.单看这句话貌似有点抽象,其实比较简单. 以李云龙的独立团为例,目的要统计赵嘉宇一战共歼灭敌人多少个.最高的级别是团,一个团有若干个营,一个营有若干个排,一个排有若干个战士.(为了简化问题,排下面就不设行政单位了).很自然的,李云龙给营长开会回去给老子统计.营长回去给各个排长开会,赶紧

java中23种设计模式之18-原型模式(Prototype pattern)

class Something{ public String something=null;}class Prototype implements Cloneable{ private String name; public Something aSomething=new Something(); public void setName(String name) { this.name=name; } public String getName() { return name; } publi

Java经典23种设计模式之创造型模式(二)

本文记录5种创造型模式的剩下两种:建造者模式(Builder).原型模式(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.一个完整的建造者模式包含以下几个概念: 1.产品类 Product public class Person { private String head; private String body; private String foot; public String getHead() { ret

Java经典23种设计模式之创造型模式(一)

设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计模式有23种,分三个大类型: 创建型模式(5) .结构型模式(7).行为型模式(11),5 + 7 +11 = 23.网上一搜也都是一大把了,这里不过个人作的记录.本文记录创造型模式里的工厂方法(Factory Method).抽象工厂(Abstract Factory).单例模式这三种.力求透彻.