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);
}
}