設(shè)計(jì)模式 Java Design Pattern

1.設(shè)計(jì)模式(Design Pattern)23

按目的準(zhǔn)則分類(lèi):

創(chuàng)建型(creational) 5 與對(duì)象的創(chuàng)建有關(guān)

Singleton Prototype FactoryMethod AbstractFactory Builder

結(jié)構(gòu)型(structural) 7 處理類(lèi)與對(duì)象的組合

Adapter Decorator Composite Proxy
Bridge Facade Flyweitht

行為型(behavioral) 11 對(duì)類(lèi)或?qū)ο笤鯓咏换ズ驮鯓臃峙渎氊?zé)進(jìn)行描述

TemplateMethod Strategy Observer
Interpreter Chain of Responsibility Command
Iterator Mediator Memento State Visitor

2.功能介紹

創(chuàng)建型

模式 功能
單例 確保有且只有一個(gè)對(duì)象被創(chuàng)建保證一個(gè)類(lèi)僅有一個(gè)實(shí)例吴叶,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)
原型 用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi)腔稀,并且通過(guò)拷貝這個(gè)原型來(lái)創(chuàng)建新的對(duì)象
工廠方法 定義一個(gè)用于創(chuàng)建對(duì)象的接口陵刹,讓子類(lèi)決定將哪一個(gè)類(lèi)實(shí)例化FactoryMehtod使一個(gè)類(lèi)的實(shí)例化延遲到其子類(lèi)
抽象工廠 提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴(lài)對(duì)象的接口频敛,無(wú)需指定他們具體的類(lèi)
建造者 將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離银室,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示

結(jié)構(gòu)型

模式 功能
裝飾者 包裝一個(gè)對(duì)象磺浙,以提供新的行為 動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)修噪,就擴(kuò)展功能而言,比生成子類(lèi)方式更靈活
適配器 封裝對(duì)象籍凝,并提供不同的接口 將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口周瞎,該模式使得原本由于接口不兼容而不能一起工作的類(lèi)可以一起工作
代理 包裝對(duì)象,以控制對(duì)此對(duì)象的訪問(wèn) 為目標(biāo)對(duì)象提供一個(gè)代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)
門(mén)面 簡(jiǎn)化一群類(lèi)的接口 為子系統(tǒng)中的一組接口提供一個(gè)一致的界面 定義了一個(gè)高層接口饵蒂,這個(gè)接口使得這一子系統(tǒng)更加容易使用
組合 客戶用一致的方法處理對(duì)象集合和單個(gè)對(duì)象 將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)声诸,它使得客戶對(duì)單個(gè)對(duì)象和復(fù)合對(duì)象的使用具有一致性
橋接 將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化
享元 運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象

行為型

模式 功能
策略 封裝可以互換的行為退盯,并使用委托來(lái)決定要使用哪一個(gè) 定義一系列的算法彼乌,把它們一個(gè)個(gè)封裝起來(lái),并且使它們可相互替換 該模式使得算法的變化可獨(dú)立于使用它的客戶
迭代器 在對(duì)象的集合中游走渊迁,而不暴露集合的實(shí)現(xiàn) 提供一種方法順序訪問(wèn)一個(gè)聚合對(duì)象中各個(gè)元素慰照,而又不需暴露該對(duì)象的內(nèi)部表示
狀態(tài) 封裝了基于狀態(tài)的行為,并使用委托在行為之間切換 允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)琉朽,改變它的行為毒租,對(duì)象看起來(lái)似乎修改了它所屬的類(lèi)
觀察者 讓對(duì)象能夠在狀態(tài)改變時(shí)被通知 定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,以便當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí)箱叁,所有依賴(lài)于它的對(duì)象都得到通知并自動(dòng)刷新
模板方法 由子類(lèi)決定如何實(shí)現(xiàn)一個(gè)算法中的步驟 定義一個(gè)操作中的算法的骨架墅垮,而將一些步驟延遲到子類(lèi)中 該模式使得子類(lèi)可以不改變一個(gè)算法的結(jié)構(gòu)即可重新定義該算法的某些特定步驟
命令 封裝請(qǐng)求成為對(duì)象
中介 用一個(gè)中介對(duì)象來(lái)封裝一系列的對(duì)象交互 中介者使各對(duì)象不需要顯式的相互引用,從而使其耦合松散耕漱,而且可以獨(dú)立的改變它們之間的交互
備忘錄 在不破壞封裝性的前提下算色,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)螟够,這樣以后可將該對(duì)象恢復(fù)到保存的狀態(tài)
解析器 給定一個(gè)語(yǔ)言灾梦,定義它的文法的一種表示峡钓,并定義一個(gè)解釋器,該解釋器使用該表示來(lái)解釋語(yǔ)言中的句子
責(zé)任鏈 為解除請(qǐng)求的發(fā)送者和接收者之間耦合若河,而使多個(gè)對(duì)象都有機(jī)會(huì)處理這個(gè)請(qǐng)求能岩,將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求牡肉,直到有一個(gè)對(duì)象處理它
訪問(wèn)者 表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作捧灰,它使你可以在不改變各元素的類(lèi)的前提下定義作用于這些元素的新操作

3.設(shè)計(jì)原則(Seven Principles of Design Patterns)

原則 解釋
開(kāi)閉 一個(gè)軟件實(shí)體應(yīng)該對(duì)擴(kuò)展開(kāi)發(fā)淆九,對(duì)修改閉合
里氏代換 任何能使用父類(lèi)的地方一定能使用子類(lèi)
依賴(lài)倒轉(zhuǎn) 要依賴(lài)于抽象统锤,不要依賴(lài)于實(shí)現(xiàn),或者使抽象不應(yīng)該依賴(lài)于細(xì)節(jié)炭庙,細(xì)節(jié)應(yīng)該依賴(lài)于抽象
合成聚合復(fù)用 盡量使用合成聚合而不是繼承去實(shí)現(xiàn)復(fù)用
迪米特法則 一個(gè)軟件實(shí)體應(yīng)該盡可能少的與其它實(shí)體發(fā)生相互作用
接口隔離 應(yīng)當(dāng)為客戶提供盡可能小的單獨(dú)的接口而不應(yīng)該提供大的綜合性的接口
Open Close Principle Software entities like classes, modules and functions should be open for extension but closed for modifications. Template Pattern Strategy Pattern
Single Responsibility Principle A class should have only one reason to change.
Liskov Substitution Principle Derived types must be completely substitutable for their base types
Dependency Inversion Principle High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions.
Interface Segregation Principle Clients should not be forced to depend upon interfaces that they don't use.
Law of Demeter(Principle of Least Knowledge) Only talk to your immediate friends

4.The 23 Gang of Four Design Patterns (Cheat Sheet)

委托”是一種極端形式的對(duì)象組合饲窿,可以始終用于替換繼承。委托涉及兩個(gè)對(duì)象:“發(fā)件人”將自己傳遞給“委托人”焕蹄,讓委托人引用發(fā)件
監(jiān)聽(tīng)者模式
并發(fā)模式
線程池模式

1 Singleton

Ensure a class only has one instance, and provide a global point of access to it.

單例模式

    public class SimpleSingleton {
    private static SimpleSingleton instance;
    private SimpleSingleton(){}
    public static SimpleSingleton getInstance(){
        if(instance == null)
            instance = new SimpleSingleton();
        return instance;
    }
}
使用懶加載模式逾雄,在多線程中可能會(huì)創(chuàng)建多個(gè)實(shí)例
把getInstance()設(shè)置為synchronized,不高效,只能有一個(gè)線程可以調(diào)用該方法腻脏,其余的會(huì)排隊(duì)等待
只同步代碼塊(雙重檢驗(yàn)鎖)  可能未完全初始化  重排序
使用靜態(tài)內(nèi)部類(lèi)比較好    
2 Prototype

Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.

clone 復(fù)制

3 Factory Method

Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

4 Abstract Factory

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

工廠模式(簡(jiǎn)單工廠方法 工廠方法/靜態(tài)工廠方法 抽象工廠) Collection Iterator iterator()

        //自己動(dòng)手  需要時(shí)自己new一個(gè)對(duì)象
        //不使用設(shè)計(jì)模式  晚餐  米飯 面條 水餃
        Dinner dinnerSelf = new Noodle();
        System.out.println(dinnerSelf);

        //保姆動(dòng)手(類(lèi)似小作坊 什么都能自己動(dòng)手做)
        //簡(jiǎn)單工廠方法設(shè)計(jì)模式
        Dinner dinnerSimple = new SimpleFactory().getDinner("noodle");
        System.out.println(dinnerSimple);
        Dinner dinnerAbstract = new DinnerFactory().getNoodle();
        System.out.println(dinnerAbstract);

        //黃燜雞米飯飯館 東北餃子店 蘭州拉面  飯店(專(zhuān)門(mén)的工廠 專(zhuān)業(yè)做一種產(chǎn)品)
        //工廠方法設(shè)計(jì)模式   接口      
        
        Dinner dinnerMehod = new NoodleFactory().getDinner();
        System.out.println(dinnerMehod);        
        //美團(tuán)外賣(mài)  外賣(mài)平臺(tái)(大型百貨 什么都能買(mǎi)到并且都是專(zhuān)門(mén)工廠提供的 )
        //抽象工廠設(shè)計(jì)模式  不僅賣(mài)飯鸦泳,賣(mài)食材,送飯永品,等等一些列  families
        //手機(jī)工廠 小米 華為 oppo 不僅生產(chǎn)手機(jī) 生產(chǎn)手機(jī)配件  電池 耳機(jī) 等等
        
        //抽象產(chǎn)品可是是一個(gè)或多個(gè)做鹰,從而構(gòu)成一個(gè)或多個(gè)產(chǎn)品族 (手機(jī)族 電池族 耳機(jī)族)
        //在只有一個(gè)產(chǎn)品族的情況下,抽象工廠模式實(shí)際上退化到工廠方法模式
                
5 Builder

Separate the construction of a complex object from its representation so that the same construction processes can create different representations.

//具體生成器
public class DateBuilder2 implements IDateBuilder{
    private MyDate myDate;
    public DateBuilder2(MyDate myDate){
        this.myDate = myDate;
    }
    @Override
    public IDateBuilder buildDate(int y, int m, int d) {
        myDate.date = y+" "+m+" "+d;
        return this;
    }
    @Override
    public String date() {
        return myDate.date;
    }
}

public class TestUse {
    public static void main(String args[]){
        MyDate date = new MyDate();
        IDateBuilder builder;
        builder = new DateBuilder1(date).buildDate(2066, 3, 5).buildDate(2066, 3, 6);
        System.out.println(builder.date());
        builder = new DateBuilder2(date).buildDate(2066, 3, 5).buildDate(2066, 3, 6);
        System.out.println(builder.date());
    }
}
//指揮者
public class Derector {
    private IDateBuilder builder;
    public Derector(IDateBuilder builder){
        this.builder = builder;
    }
    public String getDate(int y,int m,int d){
        builder.buildDate(y, m, d);
        return builder.date();
    }
}

//生成器模式將對(duì)象的構(gòu)造過(guò)程與創(chuàng)建該對(duì)象解耦鼎姐,使對(duì)象的創(chuàng)建更加靈活有彈性
//當(dāng)增加新的具體的生產(chǎn)器時(shí)钾麸,不必修改指揮者的代碼,滿足開(kāi)-閉原則
6 Proxy

Provide a surrogate or placeholder for another object to control access to it.

7 Adapter

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatibility interfaces.

//對(duì)象適配器
public class ObjectAdapter implements Target{
    private Adaptee adaptee;
    public ObjectAdapter(){
        super();
        adaptee = new Adaptee();
    }
    @Override
    public void playFlac(Object src) {
        //可能需要對(duì)src作處理
        adaptee.playMp3(src);
    }
}

public class TestUse {
    public static void main(String args[]){
        BookAdapter books = new BookAdapter();
        books.add("think in java");
        books.add("c++ primer");
        books.add("伊索寓言");
        Iterator<String> iterator = books.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
//適配器
public class BookAdapter extends Book implements Iterable<String>{
    @Override
    public Iterator<String> iterator() {
        return new IteratorAdapter(getEnum());
    }
}
//適配器炕桨,目標(biāo)就是Iterator饭尝,被適配者是Enumeration
public class IteratorAdapter implements Iterator<String> {
    Enumeration<String> myEnum;
    public IteratorAdapter(Enumeration<String> myEnum){
        this.myEnum = myEnum;
    }
    @Override
    public boolean hasNext() {
        return myEnum.hasMoreElements();
    }
    @Override
    public String next() {
        return myEnum.nextElement();
    }
}
8 Decorator

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

裝飾模式使用被裝飾類(lèi)的一個(gè)子類(lèi)的實(shí)例,把客戶端的調(diào)用委派到被裝飾類(lèi)献宫,裝飾模式的關(guān)鍵在于這種擴(kuò)展是完全透明的钥平。裝飾者與被裝飾者擁有共同的超類(lèi),繼承的目的是繼承類(lèi)型姊途,而不是行為涉瘾。
使用了裝飾器的對(duì)象,功能已經(jīng)增強(qiáng)了吭净,而且可以使用多個(gè)裝飾器
java.io
9 Composite

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

10 Facade

Provide a unified interface to a set of interfaces in a system. Fa?ade defines a higher-level interface that makes the subsystem easier to use.

11 Bridge

Decouple an abstraction from its implementation so that the two can vary independently.

橋接模式中有4種角色:

    抽象
    細(xì)化抽象
    實(shí)現(xiàn)者
    具體實(shí)現(xiàn)者
    JDBC is a typical application of Bridge Pattern
12 Flyweight

Use sharing to support large numbers of fine-grained objects efficiently. A flyweight is a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independent object in each context; it’s indistinguishable from an instance of the object that’s not shared.

 享元模式包括三種角色:

    享元接口(Plyweight):定義了對(duì)外公開(kāi)的獲取其內(nèi)部數(shù)據(jù)和接收外部數(shù)據(jù)的方法睡汹。
    具體享元(Concrete Plyweight):享元接口的實(shí)現(xiàn)。
    享元工廠(Plyweight Factory):該類(lèi)的實(shí)例負(fù)責(zé)創(chuàng)建和管理享元對(duì)象寂殉,用戶或其他對(duì)象必須請(qǐng)求他以獲取一個(gè)享元對(duì)象囚巴。
//享元工廠
class FlyweightFactory{
    HashMap<String, IFlyweight> flyweights = new HashMap<String, IFlyweight>();
    IFlyweight getFlyweight(String value){
        IFlyweight flyweight = flyweights.get(value);
        if(flyweight == null){
            flyweight = new Flyweight(value);
            flyweights.put(value, flyweight);
        }
        return flyweight;
    }
    public int size(){
        return flyweights.size();
    }
}
13 Strategy

Defines a family of algorithms, encapsulates each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients who use it.

策略模式中包括三種角色:

策略(Strategy):一個(gè)接口,定義了若干個(gè)算法(抽象方法)。
具體策略(ConcreteStrategy):策略的實(shí)現(xiàn)彤叉。
上下文/環(huán)境(Context):依賴(lài)于策略接口的類(lèi)庶柿。
策略模式的重心不是如何實(shí)現(xiàn)算法,而是如何組織秽浇、調(diào)用這些算法浮庐,從而讓程序結(jié)構(gòu)更靈活,具有更好的維護(hù)性和擴(kuò)展性柬焕。
public class TestUse {
    public static void main(String args[]){
        Object data = "數(shù)據(jù)";
        ISaveData saveData = new SaveToRedis();
        SaveClient client = new SaveClient(saveData);
        client.save(data);
        client.setSaveData(new SaveToFile());
        client.save(data);
    }
}
14 Template

Define a skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.

15 Observer

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

觀察者模式中的數(shù)據(jù)有推和拉的區(qū)別
推的方式會(huì)將主題更改的內(nèi)容全部直接推給客戶端
拉的方式就是主題的數(shù)據(jù)更新后审残,不直接將數(shù)據(jù)推給客戶端,
而是先推送一個(gè)通知并提供對(duì)應(yīng)的方法供客戶端拉取數(shù)據(jù)  //給客戶端推送一個(gè)標(biāo)志
16 Chain of Responsibility

Avoid coupling the sender of a request to its receiver by giving more then one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

//第三個(gè)具體處理者斑举,處理>=0但小于10的
public class Handler3 implements Handler {
    private Handler next;
    @Override
    public int handleRequest(int n) {
        if(n<=Integer.MAX_VALUE) return n;
        else{
            if(next==null)
                throw new NullPointerException("next 不能為空");
            return next.handleRequest(n);
        }
    }
    @Override
    public void setNextHandler(Handler next) {
        this.next = next;
    }
}
//過(guò)濾器(Filter)  Log4j記錄日志搅轿,配置級(jí)別
17 Iterator

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

主要的角色是集合、具體集合富玷、迭代器璧坟、具體迭代器
18 Command

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

public class TestUse {
    public static void main(String args[]) throws Exception{
        //接收者
        MakeFile makeFile = new MakeFile();
        //命令
        CommandCreate create = new CommandCreate(makeFile);
        CommandDelete delete = new CommandDelete(makeFile);
        //請(qǐng)求者
        Client client = new Client();
        //執(zhí)行命令
        client.setCommand(create).executeCommand("d://test1.txt");
        client.setCommand(create).executeCommand("d://test2.txt");
        client.setCommand(delete).executeCommand("d://test2.txt");
    }
}//執(zhí)行完后在D盤(pán)會(huì)有一個(gè)test1.txt的文件,test2.txt本頁(yè)創(chuàng)建了赎懦,又被刪除

19 Mediator

Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and lets you vary their interaction independently.

//具體同事
public class PersistentDB implements IPersistent{
    private Object data;
    @Override
    public void getData(Object data, Midiator midiator) {
        getData(data);
        midiator.notifyOther(this, data);
    }
    @Override
    public void saveData() {
        System.out.println(data + " 已保存到數(shù)據(jù)庫(kù)");
    }
    @Override
    public void getData(Object data) {
        this.data = data;
        saveData();
    }
}

//具體中介者
public class Midiator {
    PersistentDB persistentDB;//此處可以使用List來(lái)存放所有的同事
    PersistentFile persistentFile;
    public Midiator setPersistentDB(PersistentDB persistentDB) {
        this.persistentDB = persistentDB;
        return this;
    }
    public Midiator setPersistentFile(PersistentFile persistentFile) {
        this.persistentFile = persistentFile;
        return this;
    }
    public void notifyOther(IPersistent persistent,Object data){
        if(persistent instanceof PersistentDB)//如果同事都放在List中雀鹃,此處遍歷即可
            persistentFile.getData(data);
        if(persistent instanceof PersistentFile)
            persistentDB.getData(data);
    }
}
public class TestUse {
    public static void main(String args[]){
        Object data = "數(shù)據(jù)";
        PersistentDB persistentDB = new PersistentDB();
        PersistentFile persistentFile = new PersistentFile();
        Midiator midiator = new Midiator();
        midiator.setPersistentDB(persistentDB).setPersistentFile(persistentFile);
        persistentDB.getData(data, midiator);
        persistentFile.getData(data, midiator);
    }
}//輸出(省略了換行符):數(shù)據(jù) 已保存到數(shù)據(jù)庫(kù)數(shù)據(jù) 已保存到文件數(shù)據(jù) 已保存到文件數(shù)據(jù) 已保存到數(shù)據(jù)庫(kù)


20 State

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

//具體狀態(tài)
public enum SaveSmallData implements ISaveData{
    instance;
    @Override
    public void save(Object data) {
        System.out.println("保存到Redis:" + data);
    }
}

public class TestUse {
    public static void main(String args[]){
        String smallData = "小數(shù)據(jù)";
        String middleData = "介于小數(shù)據(jù)和大數(shù)據(jù)之間的數(shù)據(jù)";
        String bifgData = "這里就假定這是一個(gè)很大很大很大的數(shù)據(jù)";
        SaveDataController saveDataController = new SaveDataController();
        saveDataController.save(smallData);
        saveDataController.save(middleData);
        saveDataController.save(bifgData);
    }
}
21 Interpreter

Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

    解釋器模式一般包括四種角色:
    抽象表達(dá)式:該角色為一個(gè)接口,負(fù)責(zé)定義抽象的解釋操作励两。
    終結(jié)符表達(dá)式:實(shí)現(xiàn)抽象表達(dá)式接口的類(lèi)黎茎。
    非終結(jié)表達(dá)式:也是實(shí)現(xiàn)抽象表達(dá)式的類(lèi)。
    上下文(Context):包含解釋器之外的一些全局信息伐蒋。
    
    使用該模式設(shè)計(jì)程序一般需要三個(gè)步驟:
    解析語(yǔ)句中的動(dòng)作標(biāo)記工三。
    將標(biāo)記規(guī)約為動(dòng)作。
    執(zhí)行動(dòng)作先鱼。
22 Memento

Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.

備忘錄模式又叫做快照模式(Snapshot Pattern)或Token模式俭正,是對(duì)象的行為模式。 備忘錄對(duì)象是一個(gè)用來(lái)存儲(chǔ)另外一個(gè)對(duì)象內(nèi)部狀態(tài)的快照的對(duì)象焙畔。
三種角色:備忘錄(Memento)角色     發(fā)起人(Originator)角色   負(fù)責(zé)人(Caretaker)角色
//簡(jiǎn)單的備忘錄模式
public class SimpleMemento {
    public static void main(String[] args) throws Exception {
        Originator originator = new Originator();//發(fā)起人掸读,要被保存的對(duì)象,是他創(chuàng)建要保存的信息
        Caretaker caretaker = new Caretaker();   //輔助保存的對(duì)象
        originator.setState("stateOne");    //設(shè)置狀態(tài)
        caretaker.saveMemento(originator.createMemento());      //保存狀態(tài)
        originator.setState("stateTwo");    //修改狀態(tài)
        originator.recoverMemento(caretaker.recoverMemento());  //恢復(fù)狀態(tài)
    }
}
23 Visitor

Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

訪問(wèn)者模式可以在Visitor類(lèi)中集中定義一些關(guān)于集合中對(duì)象的操作
動(dòng)態(tài)雙重分派也算是完成了(通過(guò)調(diào)用一個(gè)其它對(duì)象的方法,傳入自己宏多,在其他類(lèi)的這個(gè)方法中再通過(guò)傳入的這個(gè)參數(shù)調(diào)用自己
//VIP用戶儿惫,具體元素
public class UserVIP implements User{
    String estimation;
    public UserVIP(String estimation){
        this.estimation = estimation;
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
    String getEstimation(){
        return estimation;
    }
}

//具體訪問(wèn)者
public class APPOwner implements Visitor{
    @Override
    public void visit(UserVIP user) {
        String estimation = user.getEstimation();
        if(estimation.length()>5)
            System.out.println("記錄一條有效反饋:" + estimation);
    }
    @Override
    public void visit(UserOrdinary user) {
        String estimation = user.getEstimation();
        if(estimation.length()>10)
            System.out.println("記錄一條有效反饋:" + estimation);
    }
}

5 參考文獻(xiàn)

  1. The 23 Gang of Three Design Patterns
  2. Gang Of Four (GoF) Design Patterns
  3. Design Patterns in Java Tutorial
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伸但,隨后出現(xiàn)的幾起案子肾请,更是在濱河造成了極大的恐慌,老刑警劉巖更胖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铛铁,死亡現(xiàn)場(chǎng)離奇詭異隔显,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)饵逐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)括眠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人倍权,你說(shuō)我怎么就攤上這事掷豺。” “怎么了薄声?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵当船,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我奸柬,道長(zhǎng)生年,這世上最難降的妖魔是什么婴程? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任廓奕,我火速辦了婚禮,結(jié)果婚禮上档叔,老公的妹妹穿的比我還像新娘桌粉。我一直安慰自己,他們只是感情好衙四,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布铃肯。 她就那樣靜靜地躺著,像睡著了一般传蹈。 火紅的嫁衣襯著肌膚如雪押逼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天惦界,我揣著相機(jī)與錄音挑格,去河邊找鬼。 笑死沾歪,一個(gè)胖子當(dāng)著我的面吹牛漂彤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灾搏,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼挫望,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了狂窑?” 一聲冷哼從身側(cè)響起媳板,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泉哈,沒(méi)想到半個(gè)月后蛉幸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體到旦,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年巨缘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了添忘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡若锁,死狀恐怖搁骑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情又固,我是刑警寧澤仲器,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站仰冠,受9級(jí)特大地震影響乏冀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洋只,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一辆沦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧识虚,春花似錦肢扯、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至肛循,卻和暖如春铭腕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背多糠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工累舷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人熬丧。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓笋粟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親析蝴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子害捕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,294評(píng)論 0 10
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,399評(píng)論 0 23
  • 之前會(huì)認(rèn)為有的人是你一生的摯友,后來(lái)才發(fā)現(xiàn)她給你的傷比給你的糖多闷畸,多到你自己無(wú)法治愈尝盼,凝結(jié)成痕。也許她就是你...
    不開(kāi)花的仙人掌上雨初晴閱讀 77評(píng)論 0 0
  • 真的不敢相信一年,就這樣結(jié)束了峰髓,大概我對(duì)于一年的概念,不是在熱熱鬧鬧的除夕之夜佩捞,聽(tīng)著春節(jié)聯(lián)歡晚會(huì)所謂的倒計(jì)時(shí),才意...
    酒笙清梅閱讀 458評(píng)論 5 3
  • 今年九月的天有些微微涼蕾哟,秋風(fēng)似乎比以往來(lái)得要更早一些一忱。 今天坐車(chē)路過(guò)你們學(xué)校,本想和以往一樣在群里發(fā)個(gè)定位谭确,后...
    半分微光閱讀 523評(píng)論 0 4