GOF23(java設(shè)計(jì)模式)--行為型模式

職責(zé)鏈模式、迭代器模式刹衫、中介者模式醋寝、命令模式搞挣、解釋器模式、訪問者模式音羞、策略模式囱桨、模版方法模式、狀態(tài)模式嗅绰、觀察者模式舍肠、備忘錄模式
一、職責(zé)鏈模式(Chain of responsibility)
1.1窘面、作用:將能夠處理同一類請(qǐng)求的對(duì)象連成一條鏈翠语,所提交的請(qǐng)求沿著鏈傳遞,鏈上的對(duì)象逐個(gè)判斷是否有能力處理該請(qǐng)求财边,如果能則處理啡专,如果不能則傳遞給鏈上的下一個(gè)對(duì)象
1.2、UML圖:


職責(zé)鏈模式.png

1.3制圈、示例:

public class 請(qǐng)假條 {
    private String name;
    private int days;
    private String reason;
    public 請(qǐng)假條(String name, int days, String reason) {
        super();
        this.name = name;
        this.days = days;
        this.reason = reason;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getDays() {
        return days;
    }
    public void setDays(int days) {
        this.days = days;
    }
    public String getReason() {
        return reason;
    }
    public void setReason(String reason) {
        this.reason = reason;
    }
}
--------------------------------------------------------------------------------
public abstract class 領(lǐng)導(dǎo) {
    protected String name;
    protected 領(lǐng)導(dǎo) nextLeader;
    public 領(lǐng)導(dǎo)(String name) {
        super();
        this.name = name;
    }
    public void setNextLeader(領(lǐng)導(dǎo) nextLeader) {
        this.nextLeader = nextLeader;
    }   
    public abstract void handelRequest(請(qǐng)假條 request);
}
--------------------------------------------------------------------------------
public class 主任 extends 領(lǐng)導(dǎo){
    public 主任(String name) {
        super(name);
    }
    @Override
    public void handelRequest(請(qǐng)假條 request) {
        if(request.getDays()<3){
            System.out.println("主任審批通過");
        }else{
            if(this.nextLeader!=null){
                this.nextLeader.handelRequest(request);
            }
        }
    }
}
class 經(jīng)理 extends 領(lǐng)導(dǎo){
    public 經(jīng)理(String name) {
        super(name);
    }
    @Override
    public void handelRequest(請(qǐng)假條 request) {
        if(request.getDays()<10){
            System.out.println("經(jīng)理審批通過");
        }else{
            if(this.nextLeader!=null){
                this.nextLeader.handelRequest(request);
            }
        }
    }
}
class 總經(jīng)理 extends 領(lǐng)導(dǎo){
    public 總經(jīng)理(String name) {
        super(name);
    }
    @Override
    public void handelRequest(請(qǐng)假條 request) {
        if(request.getDays()<30){
            System.out.println("總經(jīng)理審批通過");
        }else{
            if(this.nextLeader!=null){
                this.nextLeader.handelRequest(request);
            }
        }
    }
}
--------------------------------------------------------------------------------
public class Client {
    public static void main(String[] args) {
        領(lǐng)導(dǎo) a = new 主任("張主任");
        領(lǐng)導(dǎo) b = new 經(jīng)理("李經(jīng)理");
        領(lǐng)導(dǎo) c = new 總經(jīng)理("王總經(jīng)理");
        a.setNextLeader(b);
        b.setNextLeader(c);
        請(qǐng)假條 leaveRequest = new 請(qǐng)假條("蔡立亮", 2, "病假");
        a.handelRequest(leaveRequest);
    }
}
--------------------------------------------------------------------------------
結(jié)果:
主任審批通過
--------------------------------------------------------------------------------
總結(jié):職責(zé)鏈模式通過把多個(gè)處理邏輯對(duì)象串在一起,按順序進(jìn)行處理畔况,前面處理不了的就丟到后面的處理鲸鹦,這樣可以靈活的增減處理過程

二、迭代器模式(Iterator)
2.1跷跪、作用:定義一個(gè)迭代器馋嗜,可以方便的對(duì)聚合對(duì)象進(jìn)行遍歷處理
2.2、UML圖:


迭代器模式.png

2.3吵瞻、示例:

public interface 迭代器接口 {
    public void first();//指向第一個(gè)對(duì)象
    public void next();//指向下一個(gè)對(duì)象
    public boolean hasNext();//是否還有對(duì)象
    public boolean isFirst();//是否是最前一個(gè)對(duì)象
    public boolean isDone();//是否是最后一個(gè)對(duì)象
    public Object currentItem();//當(dāng)前對(duì)象
}
--------------------------------------------------------------------------------
public class 自定義迭代器 implements 迭代器接口{
    private List<Object> list;
    private int cursor = 0;
    public 自定義迭代器(List<Object> list){
        this.list = list;
    }
    public void first() {
        cursor = 0;
    }
    public void next() {
        cursor++;
    }
    public boolean hasNext() {
        if(cursor>=list.size()){return false;}else{return true;}
    }
    public boolean isFirst() {
        return cursor==0?true:false;
    }
    public boolean isDone() {
        return cursor==(list.size()-1)?true:false;
    }
    public Object currentItem() {
        return list.get(cursor);
    }
}
--------------------------------------------------------------------------------
public abstract class 聚集抽象類 {
    protected List<Object> list;
    public 聚集抽象類(){
        this.list = new ArrayList<Object>();
    }
    public void add(Object o){
        list.add(o);
    }
    public void remove(Object o){
        list.remove(o);
    }
    public abstract 迭代器接口 getIterator();
}
--------------------------------------------------------------------------------
public class 聚集具體類 extends 聚集抽象類{   
    public 聚集具體類() {
        super();
    }
    @Override
    public 迭代器接口 getIterator() {
        return new 自定義迭代器(super.list);
    }
}
--------------------------------------------------------------------------------
public class 請(qǐng)假條 {
    private String name;
    private int days;
    private String reason;
    public 請(qǐng)假條(String name, int days, String reason) {
        super();
        this.name = name;
        this.days = days;
        this.reason = reason;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getDays() {
        return days;
    }
    public void setDays(int days) {
        this.days = days;
    }
    public String getReason() {
        return reason;
    }
    public void setReason(String reason) {
        this.reason = reason;
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        聚集抽象類 qjts = new 聚集具體類();
        請(qǐng)假條 qjt1 = new 請(qǐng)假條("蔡立亮1", 13, "病假1");
        請(qǐng)假條 qjt2 = new 請(qǐng)假條("蔡立亮2", 23, "病假2");
        請(qǐng)假條 qjt3 = new 請(qǐng)假條("蔡立亮3", 33, "病假3");
        請(qǐng)假條 qjt4 = new 請(qǐng)假條("蔡立亮4", 43, "病假4");
        qjts.add(qjt1);qjts.add(qjt2);qjts.add(qjt3);qjts.add(qjt4);
        迭代器接口 ddq = qjts.getIterator();
        while(ddq.hasNext()){
            請(qǐng)假條 qjt = (請(qǐng)假條) ddq.currentItem();
            System.out.println(qjt.getName()+qjt.getDays()+qjt.getReason());
            ddq.next();
        }
    }
}
--------------------------------------------------------------------------------
結(jié)果:
蔡立亮113病假1
蔡立亮223病假2
蔡立亮333病假3
蔡立亮443病假4
--------------------------------------------------------------------------------
總結(jié):略...

三葛菇、中介者模式(Mediator)
3.1、作用:解耦多個(gè)同事對(duì)象之間的交互關(guān)系橡羞。每個(gè)對(duì)象都持有中介者對(duì)象的引用,只跟中介者對(duì)象打交道卿泽。我們通過中介者對(duì)象統(tǒng)一管理這些交互關(guān)系
3.2莺债、好處:


image.png

3.3、UML圖:


中介者模式.png

3.4签夭、示例:
public interface 部門接口 {
    public String getName();//獲取部門名稱
    public void selfAction(部門接口 dept);//內(nèi)部動(dòng)作
    public void outAction(部門接口 dept);//外部動(dòng)作
}
class 人事部 implements 部門接口{
    private 中介者接口 mediator;
    private String name;
    public 人事部(String name,中介者接口 mediator) {
        super();
        this.name = name;
        this.mediator = mediator;
    }
    public String getName() {
        return name;
    }
    public void selfAction(部門接口 dept) {
        System.out.println("接到"+dept.getName()+"通知齐邦,我們現(xiàn)在就去招人");
    }
    public void outAction(部門接口 dept) {
        mediator.command(this,dept);
    }
}
class 財(cái)務(wù)部 implements 部門接口{
    private 中介者接口 mediator;
    private String name;
    public 財(cái)務(wù)部(String name,中介者接口 mediator) {
        super();
        this.name = name;
        this.mediator = mediator;
    }
    public String getName() {
        return name;
    }
    public void selfAction(部門接口 dept) {
        System.out.println("接到"+dept.getName()+"通知,我們現(xiàn)在去發(fā)工資");
    }
    public void outAction(部門接口 dept) {
        mediator.command(this,dept);
    }
}
class 服務(wù)部 implements 部門接口{
    private 中介者接口 mediator;
    private String name;
    public 服務(wù)部(String name,中介者接口 mediator) {
        super();
        this.name = name;
        this.mediator = mediator;
    }
    public String getName() {
        return name;
    }
    public void selfAction(部門接口 dept) {
        System.out.println("接到"+dept.getName()+"通知第租,我們現(xiàn)在去服務(wù)客戶");
    }
    public void outAction(部門接口 dept) {
        mediator.command(this,dept);
    }
}
--------------------------------------------------------------------------------
public interface 中介者接口 {
    public void regester(部門接口 dept);
    public void command(部門接口 dept,部門接口 dept2);
}
--------------------------------------------------------------------------------
public class 中介者  implements 中介者接口{
    private Map map = new HashMap<String,部門接口>();
    public void regester(部門接口 dept) {
        map.put(dept.getName(), dept);
    }
    public void command(部門接口 dept,部門接口 dept2) {
        dept2.selfAction(dept);
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        中介者接口 mediator = new 中介者();
        部門接口 cwb = new 財(cái)務(wù)部("cwb",mediator);
        部門接口 rsb = new 人事部("rsb",mediator);
        部門接口 fwb = new 服務(wù)部("fwb",mediator);
        mediator.regester(cwb);
        mediator.regester(rsb);
        mediator.regester(fwb);
        cwb.outAction(rsb);
        cwb.outAction(fwb);
    }
}
--------------------------------------------------------------------------------
結(jié)果:
接到cwb通知措拇,我們現(xiàn)在就去招人
接到cwb通知,我們現(xiàn)在去服務(wù)客戶
--------------------------------------------------------------------------------
總結(jié):中介者是一個(gè)普通對(duì)象與中介對(duì)象兩兩相連的關(guān)系慎宾,即需要相互通信的對(duì)象需要持有同一個(gè)中介對(duì)象丐吓,中介對(duì)象需要持有所有需要通信的普通對(duì)象浅悉,這樣設(shè)計(jì)后,如果需要新增普通對(duì)象與其它對(duì)象通信汰蜘,就不需要改變?cè)瓕?duì)象代碼仇冯,只需要新增一個(gè)對(duì)象,然后在客戶端調(diào)用時(shí)給他設(shè)置中介對(duì)象族操,然后把他注冊(cè)到中介對(duì)象即可苛坚,滿足開閉原則

四、命令模式(Command)
4.1色难、作用:將一個(gè)請(qǐng)求對(duì)象封裝為一個(gè)對(duì)象泼舱,從而使我們可用不同的請(qǐng)求對(duì)客戶今次那個(gè)參數(shù)化;對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志枷莉,以及支持可撤銷的操作娇昙。也稱之為:動(dòng)作Action模式、事務(wù)transaction模式笤妙。
4.2冒掌、關(guān)鍵結(jié)構(gòu):Command抽象命令類、ConcreteCommand具體命令類蹲盘、Invoker調(diào)用者/請(qǐng)求者股毫、Receiver接收者、Client客戶類召衔。
4.3铃诬、UML圖:


命令模式.png

4.4、示例:

public interface 命令接口 {
    public void execute(String command);//執(zhí)行單個(gè)命令
    public void executeAll();//執(zhí)行全部命令
    public void addReceiver(命令接收者 r);//增加接受者
    public void removeReceiver(命令接收者 r);//刪除接收者
    public void addCommand(String c);//增加命令
}
--------------------------------------------------------------------------------
public class 命令類 implements 命令接口{
    private List<命令接收者> list;
    private List<String> commandlist = new ArrayList<String>();
    public 命令類() {
        super();
        this.list = new ArrayList<命令接收者>();
    }
    public void addReceiver(命令接收者 r) {
        list.add(r);
    }
    public void removeReceiver(命令接收者 r) {
        list.remove(r);
    }
    public void addCommand(String c) {
        commandlist.add(c);
    }
    public void execute(String command) {
        for(命令接收者 r : list){
            r.play(command);
        }
    }
    public void executeAll() {
        for(命令接收者 r : list){
            for(String c :commandlist){
                r.play(c);
            }
        }
        commandlist.clear();
    }
}
--------------------------------------------------------------------------------
public class 命令接收者 {
    String name;
    public 命令接收者(String name) {
        super();
        this.name = name;
    }
    public void play(String command){
        System.out.println(name+"執(zhí)行:"+command);
    }
}
--------------------------------------------------------------------------------
public class 命令調(diào)用者 {
    private 命令接口 command;
    public 命令調(diào)用者(命令接口 command) {
        super();
        this.command = command;
    }
    public void call(String c){
        command.execute(c);
    }
    public void callAll(){
        command.executeAll();
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        命令接口 command = new 命令類();
        command.addReceiver(new 命令接收者("張三"));
        command.addReceiver(new 命令接收者("李四"));
        command.addReceiver(new 命令接收者("王五"));
        命令調(diào)用者 invoker = new 命令調(diào)用者(command);
        invoker.call("起床寫代碼");
        System.out.println("-------------------");
        command.addCommand("起床洗臉");
        command.addCommand("起床吃早點(diǎn)");
        command.addCommand("起床跑步");
        invoker.callAll();
    }
}
--------------------------------------------------------------------------------
結(jié)果:
張三執(zhí)行:起床寫代碼
李四執(zhí)行:起床寫代碼
王五執(zhí)行:起床寫代碼
-------------------
張三執(zhí)行:起床洗臉
張三執(zhí)行:起床吃早點(diǎn)
張三執(zhí)行:起床跑步
李四執(zhí)行:起床洗臉
李四執(zhí)行:起床吃早點(diǎn)
李四執(zhí)行:起床跑步
王五執(zhí)行:起床洗臉
王五執(zhí)行:起床吃早點(diǎn)
王五執(zhí)行:起床跑步
--------------------------------------------------------------------------------
總結(jié):命令模式讓命令的執(zhí)行獨(dú)立為一個(gè)對(duì)象苍凛,在對(duì)象中做命令的調(diào)用時(shí)趣席,可以對(duì)指令進(jìn)行管理,從而可以實(shí)現(xiàn)事務(wù)醇蝴、撤銷等功能宣肚,但上述例子未達(dá)到事務(wù)和撤銷等目的,一般時(shí)配合備忘錄模式一起使用才能達(dá)到這種效果悠栓,本示例只是做到了管理指令钉寝,指令批量執(zhí)行的功能

五、解釋器模式(Interpreter)
5.1闸迷、介紹:是一種不常用的設(shè)計(jì)模式嵌纲,用于描述如何構(gòu)成一個(gè)簡(jiǎn)單的語言解釋器,主要用于使用面向?qū)ο笳Z言開發(fā)的編譯器和解釋器設(shè)計(jì)腥沽, 當(dāng)我們需要開發(fā)一種新的語言時(shí)逮走,可以考慮使用解釋器模式
5.2、UML今阳、示例 略過
六师溅、訪問者模式(Visitor)
6.1茅信、作用:表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作,它使我們可以在不改變個(gè)元素的類的前提下定義作用于這些元素的新操作
6.2墓臭、使用:略過
七蘸鲸、策略模式(Strategy)
7.1、作用:策略模式對(duì)應(yīng)于解決某一個(gè)問題的一個(gè)算法族窿锉,允許用戶從該算法族中任選一個(gè)算法解決某一問題酌摇,同時(shí)可以方便的更換算法或者增加新的算法,并且由客戶端決定調(diào)用哪個(gè)算法嗡载。
7.2窑多、UML圖:


策略模式.png

7.3、示例:

public interface 策略接口 {
    public double getPrice(double d);
}
class 鉆石會(huì)員 implements 策略接口{
    public double getPrice(double d) {
        return d*0.75;
    }
}
class 白金會(huì)員 implements 策略接口{
    public double getPrice(double d) {
        return d*0.85;
    }
}
class 普通會(huì)員 implements 策略接口{
    public double getPrice(double d) {
        return d*0.95;
    }
}
class 非會(huì)員 implements 策略接口{
    public double getPrice(double d) {
        return d;
    }
}
--------------------------------------------------------------------------------
public class 刷卡機(jī) {
    private 策略接口 strategy;
    public void setStrategy(策略接口 strategy) {
        this.strategy = strategy;
    }
    public void printPrice(double d){
        System.out.println(strategy.getPrice(d));
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        鉆石會(huì)員 strategy1 = new 鉆石會(huì)員();
        白金會(huì)員 strategy2 = new 白金會(huì)員();
        普通會(huì)員 strategy3 = new 普通會(huì)員();
        非會(huì)員 strategy4 = new 非會(huì)員();
        刷卡機(jī) pos = new 刷卡機(jī)();
        System.out.println("-------鉆石會(huì)員-------");
        pos.setStrategy(strategy1);
        pos.printPrice(1000);
        System.out.println("-------白金會(huì)員-------");
        pos.setStrategy(strategy2);
        pos.printPrice(1000);
        System.out.println("-------普通會(huì)員-------");
        pos.setStrategy(strategy3);
        pos.printPrice(1000);
        System.out.println("-------非會(huì)員-------");
        pos.setStrategy(strategy4);
        pos.printPrice(1000);
    }
}
--------------------------------------------------------------------------------
結(jié)果:
-------鉆石會(huì)員-------
750.0
-------白金會(huì)員-------
850.0
-------普通會(huì)員-------
950.0
-------非會(huì)員-------
1000.0
--------------------------------------------------------------------------------
總結(jié):略

八洼滚、模版方法模式(Template method)
8.1埂息、作用:處理某個(gè)流程的代碼都已經(jīng)具備但是其中某個(gè)節(jié)點(diǎn)的代碼暫時(shí)不能確定。因此遥巴,我們采用工廠方法模式千康,將這個(gè)節(jié)點(diǎn)的代碼實(shí)現(xiàn)轉(zhuǎn)移給子類完成。即:處理步驟父類中定義好铲掐,具體實(shí)現(xiàn)延遲到子類中定義拾弃。
8.2、UML圖:


模版方法模式.png

8.3迹炼、示例:

public abstract class 抽象父類 {
    public void 取號(hào)(){
        System.out.println("排隊(duì)取號(hào)");
    }
    public abstract void 辦業(yè)務(wù)();
    public void 評(píng)價(jià)(){
        System.out.println("給客戶評(píng)分");
    }
    public final void 模板(){
        this.取號(hào)();
        this.辦業(yè)務(wù)();
        this.評(píng)價(jià)();
    }
}

--------------------------------------------------------------------------------
public class 具體子類 extends 抽象父類 {
    @Override
    public void 辦業(yè)務(wù)() {
        System.out.println("窗口辦業(yè)務(wù)");
    }
}
class 具體子類2 extends 抽象父類 {
    @Override
    public void 辦業(yè)務(wù)() {
        System.out.println("柜臺(tái)辦業(yè)務(wù)");
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        抽象父類 templete = new 具體子類();
        抽象父類 templete2 = new 具體子類2();
        templete.模板();
        System.out.println("-----------------");
        templete2.模板();
    }
}
--------------------------------------------------------------------------------
結(jié)果:
排隊(duì)取號(hào)
窗口辦業(yè)務(wù)
給客戶評(píng)分
-----------------
排隊(duì)取號(hào)
柜臺(tái)辦業(yè)務(wù)
給客戶評(píng)分
--------------------------------------------------------------------------------
總結(jié);此模式,針對(duì)不同的實(shí)現(xiàn)可以有不同的子類實(shí)現(xiàn)

九颠毙、狀態(tài)模式(State)
9.1斯入、用于解決系統(tǒng)中復(fù)雜對(duì)象的狀態(tài)轉(zhuǎn)換以及不同狀態(tài)下行為的封裝問題
9.2、關(guān)鍵組成:Context環(huán)境類蛀蜜、State抽象狀態(tài)類刻两、ConcreteState具體狀態(tài)類
9.3、UML圖:


狀態(tài)模式.png

9.4滴某、示例:

public interface 狀態(tài)接口 {
    public void 行為一();
    public void 行為二();
}
--------------------------------------------------------------------------------
public class 空狀態(tài) implements 狀態(tài)接口 {
    public void 行為一() {
        System.out.println("房間空磅摹,可以住人和接受預(yù)定");
    }
    public void 行為二() {
    }
}
--------------------------------------------------------------------------------
public class 預(yù)定狀態(tài) implements 狀態(tài)接口 {
    public void 行為一() {
        System.out.println("房間已預(yù)定,不可以預(yù)定可住人");
    }
    public void 行為二() {
    }
}
--------------------------------------------------------------------------------
public class 已住狀態(tài) implements 狀態(tài)接口 {
    public void 行為一() {
        System.out.println("房間已住人霎奢,不可以預(yù)定和住人");
    }
    public void 行為二() {
    }
}
--------------------------------------------------------------------------------
public class 房間 {
    private 狀態(tài)接口 state;
    public void setState(狀態(tài)接口 state) {
        this.state = state;
        this.state.行為一();
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        房間 home= new 房間();
        home.setState(new 空狀態(tài)());
        System.out.println("---------------");
        home.setState(new 預(yù)定狀態(tài)());
        System.out.println("---------------");
        home.setState(new 已住狀態(tài)());
    }
}
--------------------------------------------------------------------------------
結(jié)果:
房間空户誓,可以住人和接受預(yù)定
---------------
房間已預(yù)定,不可以預(yù)定可住人
---------------
房間已住人幕侠,不可以預(yù)定和住人
--------------------------------------------------------------------------------
總結(jié):

十帝美、觀察者模式(Observer)
10.1、作用:觀察者模式主要用于1:N的通知晤硕,當(dāng)對(duì)象(目標(biāo)對(duì)象subject)的狀態(tài)發(fā)生變化時(shí)悼潭,他需要及時(shí)的告知一系列的對(duì)象(觀察者對(duì)象observer)庇忌,令他們做出響應(yīng)。
10.2舰褪、通知觀察者的方式:推送皆疹、拉取
10.3、UML圖:


觀察者模式.png

10.4占拍、示例:

public abstract class 抽象目標(biāo)對(duì)象類 {
    protected List<觀察者接口> list = new ArrayList<觀察者接口>();
    public abstract void Notify();//發(fā)布消息
    public abstract void setAction(String action);//設(shè)置消息
    public void regester(觀察者接口 observer){
        list.add(observer);
    }
    public void remove(觀察者接口 observer){
        list.remove(observer);
    }
}
--------------------------------------------------------------------------------
public class 具體目標(biāo)對(duì)象類A extends 抽象目標(biāo)對(duì)象類 {
    private String action;
    public void setAction(String action) {
        this.action = action;
    }
    @Override
    public void Notify() {
        for(觀察者接口 o :super.list){
            o.play(action);
        }
    }
}
--------------------------------------------------------------------------------
public class 具體目標(biāo)對(duì)象類B extends 抽象目標(biāo)對(duì)象類 {
    private String action;
    public void setAction(String action) {
        this.action = action;
    }
    @Override
    public void Notify() {
        for(觀察者接口 o :super.list){
            o.play(action);
        }
    }
}
--------------------------------------------------------------------------------
public interface 觀察者接口 {
    public void play(String action);
}
--------------------------------------------------------------------------------
public class 觀察者A implements 觀察者接口 {
    private String name;
    public 觀察者A(String name) {
        super();
        this.name = name;
    }
    public void play(String action) {
        System.out.println("觀察者A("+name+")檢測(cè)到動(dòng)作"+action);
    }
}
--------------------------------------------------------------------------------
public class 觀察者B implements 觀察者接口 {
    private String name;
    public 觀察者B(String name) {
        super();
        this.name = name;
    }
    public void play(String action) {
        System.out.println("觀察者B("+name+")檢測(cè)到動(dòng)作"+action);
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        抽象目標(biāo)對(duì)象類 subject = new 具體目標(biāo)對(duì)象類A();
        觀察者A observer1 = new 觀察者A("蔡立亮1");
        觀察者A observer2 = new 觀察者A("蔡立亮2");
        觀察者B observer3 = new 觀察者B("蔡立亮3");
        觀察者B observer4 = new 觀察者B("蔡立亮4");
        subject.regester(observer1);
        subject.regester(observer2);
        subject.regester(observer3);
        subject.regester(observer4);
        subject.setAction("開始跑步");
        subject.Notify();
    }
}
--------------------------------------------------------------------------------
結(jié)果:
觀察者A(蔡立亮1)檢測(cè)到動(dòng)作開始跑步
觀察者A(蔡立亮2)檢測(cè)到動(dòng)作開始跑步
觀察者B(蔡立亮3)檢測(cè)到動(dòng)作開始跑步
觀察者B(蔡立亮4)檢測(cè)到動(dòng)作開始跑步
--------------------------------------------------------------------------------
總結(jié):

十一略就、備忘錄模式(Memento)
11.1、作用:就是保存某個(gè)對(duì)象內(nèi)部狀態(tài)的拷貝刷喜,這樣以后就可以將該對(duì)象恢復(fù)到原先的狀態(tài)
11.2残制、關(guān)鍵組成:源發(fā)器類Originator、備忘錄類Memento掖疮、負(fù)責(zé)人類CareTaker
11.2初茶、UML圖:


備忘錄模式.png

11.3、示例:

public class 員工 {
    private String name;
    private String position;
    private double salary;
    private 備忘錄 memento = new 備忘錄();
    public 員工(String name) {
        super();
        this.name = name;
    }
    public void createMemento(){
        memento.add(new 員工Memento(name,position,salary));
    }
    public void recovery(){
        員工Memento m = memento.get();
        this.name = m.getName();
        this.position = m.getPosition();
        this.salary = m.getSalary();
    }
    
    public void print(){
        System.out.println("姓名:"+name+";崗位:"+position+";薪水:"+salary);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPosition() {
        return position;
    }
    public void setPosition(String position) {
        this.position = position;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
}
--------------------------------------------------------------------------------
public class 員工Memento {
    private String name;
    private String position;
    private double salary;
    public 員工Memento(String name, String position, double salary) {
        super();
        this.name = name;
        this.position = position;
        this.salary = salary;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPosition() {
        return position;
    }
    public void setPosition(String position) {
        this.position = position;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
}
--------------------------------------------------------------------------------
public class 備忘錄 {
    private  Stack<員工Memento> stack = new  Stack<員工Memento>();
    public void add(員工Memento m){
        stack.add(m);
    }
    public 員工Memento get(){
        int len = stack.size();
        if(len==1){
            return stack.peek();
        }else{
            return stack.pop();
        }
    }
}
--------------------------------------------------------------------------------
public class 客戶端 {
    public static void main(String[] args) {
        員工 employee = new 員工("蔡立亮");
        employee.setPosition("程序員");
        employee.setSalary(8000);
        employee.print();
        System.out.println("--------------------");
        employee.createMemento();
        employee.setPosition("項(xiàng)目經(jīng)理");
        employee.setSalary(10000);
        employee.print();
        employee.createMemento();
        employee.setPosition("技術(shù)經(jīng)理");
        employee.setSalary(15000);
        employee.print();
        employee.createMemento();
        employee.setPosition("部門經(jīng)理");
        employee.setSalary(20000);
        employee.print();
        System.out.println("---------撤回-----------");
        employee.recovery();
        employee.print();
        System.out.println("---------撤回-----------");
        employee.recovery();
        employee.print();
        System.out.println("---------撤回-----------");
        employee.recovery();
        employee.print();
        System.out.println("---------撤回-----------");
        employee.recovery();
        employee.print();
    }
}
--------------------------------------------------------------------------------
結(jié)果:
姓名:蔡立亮;崗位:程序員;薪水:8000.0
--------------------
姓名:蔡立亮;崗位:項(xiàng)目經(jīng)理;薪水:10000.0
姓名:蔡立亮;崗位:技術(shù)經(jīng)理;薪水:15000.0
姓名:蔡立亮;崗位:部門經(jīng)理;薪水:20000.0
---------撤回-----------
姓名:蔡立亮;崗位:技術(shù)經(jīng)理;薪水:15000.0
---------撤回-----------
姓名:蔡立亮;崗位:項(xiàng)目經(jīng)理;薪水:10000.0
---------撤回-----------
姓名:蔡立亮;崗位:程序員;薪水:8000.0
---------撤回-----------
姓名:蔡立亮;崗位:程序員;薪水:8000.0
--------------------------------------------------------------------------------
總結(jié):這里之所以要一個(gè)“員工Memento”類浊闪,是因?yàn)椤皢T工“類可能不是所有的屬性都需要備份恼布,只需要備份部分屬性,如果直接備份“員工”類搁宾,則顯得比較浪費(fèi)資源
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末折汞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盖腿,更是在濱河造成了極大的恐慌爽待,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翩腐,死亡現(xiàn)場(chǎng)離奇詭異鸟款,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)茂卦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門何什,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人等龙,你說我怎么就攤上這事处渣。” “怎么了蛛砰?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵罐栈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我泥畅,道長(zhǎng)悠瞬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮浅妆,結(jié)果婚禮上望迎,老公的妹妹穿的比我還像新娘。我一直安慰自己凌外,他們只是感情好辩尊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著康辑,像睡著了一般摄欲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上疮薇,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天胸墙,我揣著相機(jī)與錄音,去河邊找鬼按咒。 笑死迟隅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的励七。 我是一名探鬼主播智袭,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼掠抬!你這毒婦竟也來了吼野?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤两波,失蹤者是張志新(化名)和其女友劉穎瞳步,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腰奋,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡单起,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了氛堕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馏臭。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡野蝇,死狀恐怖讼稚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绕沈,我是刑警寧澤锐想,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站乍狐,受9級(jí)特大地震影響赠摇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一藕帜、第九天 我趴在偏房一處隱蔽的房頂上張望烫罩。 院中可真熱鬧,春花似錦洽故、人聲如沸贝攒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隘弊。三九已至,卻和暖如春荒适,著一層夾襖步出監(jiān)牢的瞬間梨熙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工刀诬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咽扇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓舅列,卻偏偏與公主長(zhǎng)得像肌割,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子帐要,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容