設計模式簡單小例子(三)行為型模式
阿新 • • 發佈:2018-12-17
終於,把設計模式小例子敲完了.....
原始碼已經上傳到了GitHub.
https://github.com/tanglonghui/DesignPatterns
設計模式簡單小例子(一) 建立型模式:
https://blog.csdn.net/qq_40687864/article/details/81064917
設計模式簡單小例子(二)結構型模式:
https://blog.csdn.net/qq_40687864/article/details/81094414
一、責任鏈模式。
package BehavioralPatterns.ChainOfResponsibility; /* * 責任鏈模式是一種設計模式。在責任鏈模式裡, * 很多物件由每一個物件對其下家的引用而連線起來形成一條鏈。 * 請求在這個鏈上傳遞,直到鏈上的某一個物件決定處理此請求。 * 發出這個請求的客戶端並不知道鏈上的哪一個物件最終處理這個請求, * 這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。 */ /* * 包含角色: * 1.Hanglder(抽象處理者) * 2.ConcreteHandler(具體處理者) * 3.Client(客戶類) * 簡單說:說不出來 *就用書上請假的小例子吧,我設 A B C 三個等級的管理者 *Retrofit設定Gson等資料解析的時候是不是用了這個設計模式?有點像 */ public class Test { public static void main(String[] args) { //造個假條 LeaveRequest l1=new LeaveRequest("1", 25); //造三個人 ConcreteHandlerA a=new ConcreteHandlerA("A"); ConcreteHandlerB b=new ConcreteHandlerB("B"); ConcreteHandlerC c=new ConcreteHandlerC("C"); //設定職責的大小,也就是處理順序 a.setHanglder(b); b.setHanglder(c); //傳送請求 a.handleRequest(l1); } } class LeaveRequest{ //假條類 private String leaveName; private int leaveDay; public LeaveRequest(String leaveName,int leaveDay) { // TODO Auto-generated constructor stub this.leaveDay=leaveDay; this.leaveName=leaveName; } public int getLeaveDay() { return leaveDay; } public String getLeaveName() { return leaveName; } public void setLeaveDay(int leaveDay) { this.leaveDay = leaveDay; } public void setLeaveName(String leaveName) { this.leaveName = leaveName; } } abstract class Handler{ protected String name; protected Handler handler; public Handler(String name) { // TODO Auto-generated constructor stub this.name=name; } public void setHanglder(Handler handler) { this.handler = handler; } public abstract void handleRequest(LeaveRequest leaveRequest); } class ConcreteHandlerA extends Handler{ public ConcreteHandlerA(String name) { super(name); // TODO Auto-generated constructor stub } @Override public void handleRequest(LeaveRequest leaveRequest) { // TODO Auto-generated method stub if(leaveRequest.getLeaveDay()<10) { System.out.println("A批准了"); }else { this.handler.handleRequest(leaveRequest); } } } class ConcreteHandlerB extends Handler{ public ConcreteHandlerB(String name) { super(name); // TODO Auto-generated constructor stub } @Override public void handleRequest(LeaveRequest leaveRequest) { // TODO Auto-generated method stub if(leaveRequest.getLeaveDay()>=10 && leaveRequest.getLeaveDay()<20) { System.out.println("B批准了"); }else { this.handler.handleRequest(leaveRequest); } } } class ConcreteHandlerC extends Handler{ public ConcreteHandlerC(String name) { super(name); // TODO Auto-generated constructor stub } @Override public void handleRequest(LeaveRequest leaveRequest) { // TODO Auto-generated method stub if(leaveRequest.getLeaveDay()>=20) { System.out.println("C批准了"); }else { this.handler.handleRequest(leaveRequest); } } }
二、命令模式。
package BehavioralPatterns.Command; /* * 命令模式(Command Pattern)是一種資料驅動的設計模式, * 它屬於行為型模式。請求以命令的形式包裹在物件中,並傳給呼叫物件。 * 呼叫物件尋找可以處理該命令的合適的物件,並把該命令傳給相應的物件,該物件執行命令。 * 設計模式一書中的定義如下: * 將一個請求封裝成為一個物件,從而使我們可用不同的請求對客戶進行引數化; * 對請求排隊或者記錄請求日誌,以及支援可撤銷的操作。命令模式是一種物件 * 行為型模式,其別名為動作模式或事務模式。 */ /* * 包含物件: * Command(抽象命令類) * ConcreteCommand(具體命令類) * Invoker(呼叫者) * Receiver(接收者) * Client(客戶類) */ public class Test { public static void main(String[] args) { Receiver receiver=new Receiver(); ConcreteCommand command=new ConcreteCommand(receiver); Invoker invoker=new Invoker(command); invoker.call(); } } //宣告一些方法 interface Command{ void execute(); } class Invoker{ //宣告一個Command型別的變數 private Command command; //傳入物件的構造器及方法 public Invoker(Command command) { // TODO Auto-generated constructor stub this.command=command; } public void setCommand(Command command) { this.command = command; } //業務方法,用於呼叫命令的方法 void call() { command.execute(); } } class Receiver{ void action() { System.out.println("我執行了你的命令"); } } class ConcreteCommand implements Command{ //宣告一個接受者的變數 Receiver receiver; //傳入接收者的構造器及方法 public ConcreteCommand(Receiver receiver) { // TODO Auto-generated constructor stub this.receiver=receiver; } public void setReceiver(Receiver receiver) { this.receiver = receiver; } //具體的執行,這裡其實可以定義一套組合鍵功能 @Override public void execute() { // TODO Auto-generated method stub receiver.action(); } }
三、直譯器模式。
package BehavioralPatterns.Interpreter; import java.util.HashMap; import java.util.Stack; /* * 直譯器模式(Interpreter Pattern)提供了評估語言的語法或表示式的方式, * 它屬於行為型模式。這種模式實現了一個表示式介面,該介面解釋一個特定的上下文。 * 這種模式被用在 SQL 解析、符號處理引擎等。 */ /* * 包含物件: * AbstractExpression(抽象表示式) * TerminalExpression(終結符表示式) * NonterminalExpression(非終結符表示式) * Context(環境類) * Client(客戶類) */ public class Test { public static void main(String[] args) { Calculator calculator=new Calculator(); String str="1 + 12 - 1"; calculator.build(str); System.out.println(calculator.compute()); } } /* * */ class Context{ /* * 環境類,上下文 * 假設我們要把一句英文翻譯為中文 * 例如 hello world * 翻譯成 你好 世界 *(>.<)這裡簡單一點學教材做加減的直譯器,省略環境類 */ private HashMap<String, String> map=new HashMap<>(); //往環境中設值 public void assign(String key,String value) { map.put(key, value); } //獲取環境中的值 String lookup(String key){ return map.get(key); } public void initData() { // map.put("hello", "你好"); map.put("world", "世界"); } } interface AbstractExpression{ int interpret(); } class TerminalEpression implements AbstractExpression{ //對於終結符表示式的解釋操作 這裡表示值 private int value; public TerminalEpression(int value) { // TODO Auto-generated constructor stub this.value=value; } @Override public int interpret() { // TODO Auto-generated method stub return this.value; } } abstract class NonterminalExpression implements AbstractExpression{ //對於非終結符的操作 類的父類 protected AbstractExpression left; protected AbstractExpression right; public NonterminalExpression(AbstractExpression left, AbstractExpression right) { this.left=left; this.right=right; } } class Add extends NonterminalExpression{ public Add(AbstractExpression left, AbstractExpression right) { super(left, right); // TODO Auto-generated constructor stub } @Override public int interpret() { // TODO Auto-generated method stub return super.left.interpret()+super.right.interpret(); } } class Sub extends NonterminalExpression{ public Sub(AbstractExpression left, AbstractExpression right) { super(left, right); // TODO Auto-generated constructor stub } @Override public int interpret() { // TODO Auto-generated method stub return super.left.interpret()-super.right.interpret(); } } //直譯器封裝類Calculator(計算器類) class Calculator{ private String statement; private AbstractExpression abstractExpression; void build(String statement) { AbstractExpression left=null,right=null; /* * 工具類中的棧 有 pop push isEmpty peek search 五個方法 */ Stack<AbstractExpression> stack=new Stack<>(); //split 使用給定的正則表示式拆分字串 //若是翻譯的話便是拆分成了單詞 String[] statementArr=statement.split(" "); for(int i=0;i<statementArr.length;i++) { if(statementArr[i].equalsIgnoreCase("+")) { left=stack.pop(); int val=Integer.parseInt(statementArr[++i]); right=new TerminalEpression(val); stack.push(new Add(left,right)); }else if(statementArr[i].equalsIgnoreCase("-")) { left=stack.pop(); int val=Integer.parseInt(statementArr[++i]); right=new TerminalEpression(val); stack.push(new Sub(left,right)); }else { stack.push(new TerminalEpression (Integer.parseInt(statementArr[i]))); } } this.abstractExpression=stack.pop(); } int compute() { return abstractExpression.interpret(); } }
四、迭代器模式。
package BehavioralPatterns.Iterator;
/*
* 迭代器模式(Iterator),提供一種方法順序訪問一個聚合物件中的各種元素,而又不暴露該物件的內部表示。
*
* 基本常見得集合類都設有自己的迭代器。
*/
/*
* 包含角色:
* Iterator(抽象迭代器)
* 一般宣告如下方法:
* 1.first()獲取第一個元素。
* 2.next() 訪問下一個元素。
* 3.hasNext()判斷是否還有下一個元素
* 4.currentItem() 獲取當前元素
* ConcreteIterator(具體迭代器)
* Aggregate(抽象聚合類)
* ConcreteAggregate(具體聚合類)
*/
public class Test {
public static void main(String[] args) {
Iterator iterator=new ConcreteAggregate().createIterator();
while(iterator.hasNext()) {
System.out.println(iterator.currentItem().toString());
iterator.next();
}
}
}
interface Iterator{
void first();
void next();
boolean hasNext();
Object currentItem();
}
interface Aggregate{
Iterator createIterator();
}
class ConcreteAggregate implements Aggregate{
private Object[] obj= {"dog","pig","cat","monkey","pig"};
@Override
public Iterator createIterator() {
// TODO Auto-generated method stub
return new ConcreteItertor();
}
private class ConcreteItertor implements Iterator{
private int currentIndex=0;
@Override
public void first() {
// TODO Auto-generated method stub
currentIndex=0;
}
@Override
public void next() {
// TODO Auto-generated method stub
if(currentIndex<obj.length) {
currentIndex++;
}
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return !(currentIndex==obj.length);
}
@Override
public Object currentItem() {
// TODO Auto-generated method stub
return obj[currentIndex];
}
}
}
五、中介者模式。
package BehavioralPatterns.Mediator;
import java.util.Hashtable;
/*
*中介者模式(Mediator Pattern)是用來降低多個物件和類之間的通訊複雜性。
*這種模式提供了一箇中介類,該類通常處理不同類之間的通訊,並支援鬆耦合,使程式碼易於維護。
*中介者模式屬於行為型模式。
*/
/*
* 包含角色:
* Mediator(抽象中介者)
* ConcreteMediator(具體中介者)
* Colleague(抽象同事類)
* ConcreteColleague(具體同事類)
*/
public class Test {
public static void main(String[] args) {
AbstractChatroom chatroom=new ChatGroup();
Member m1,m2,m3,m4,m5;
m1=new DiamondMember("1");
m2=new DiamondMember("2");
m3=new DiamondMember("3");
m4=new CommonMember("4");
m5=new CommonMember("5");
chatroom.register(m1);
chatroom.register(m2);
chatroom.register(m3);
chatroom.register(m4);
chatroom.register(m5);
m1.sendText("3", "你好");
m1.sendText("3", "你好日");
m1.sendImage("2", "1221222");
m1.sendImage("2", "1224");
m5.sendImage("1", "12");
m5.sendText("3", "ni日");
}
}
//抽象聊天室類
abstract class AbstractChatroom{
abstract void register(Member member);
abstract void sendText(String from,String to,String message);
abstract void sendImage(String from,String to,String image);
}
//抽象會員類
abstract class Member{
protected AbstractChatroom chatroom;
protected String name;
public Member(String name) {
// TODO Auto-generated constructor stub
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setChatroom(AbstractChatroom chatroom) {
this.chatroom = chatroom;
}
public AbstractChatroom getChatroom() {
return chatroom;
}
abstract void sendText(String to,String message);
abstract void sendImage(String to,String image);
void receiveText(String from,String message) {
System.out.println(from+" 發文本給送"+this.name+",內容為:"+message);
}
void receiveImage(String from,String image) {
System.out.println(from+" 發圖片給送"+this.name+",內容為:"+image);
}
}
//具體聊天室類
class ChatGroup extends AbstractChatroom{
private Hashtable<String, Member> members=new Hashtable<>();
@Override
void register(Member member) {
// TODO Auto-generated method stub
if(!members.contains(member)) {
members.put(member.getName(),member);
member.setChatroom(this);
}
}
@Override
void sendText(String from, String to, String message) {
// TODO Auto-generated method stub
Member member=members.get(to);
String newMessage=message;
//模擬不雅字元
newMessage=message.replaceAll("日", "*");
member.receiveText(from, newMessage);
}
@Override
void sendImage(String from, String to, String image) {
// TODO Auto-generated method stub
Member member=members.get(to);
//模擬圖片大小判斷
if(image.length()>5) {
System.out.println("圖片太大發送失敗");
}else {
member.receiveImage(from, image);
}
}
}
//具體普通會員
class CommonMember extends Member{
public CommonMember(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
void sendImage(String to, String image) {
// TODO Auto-generated method stub
System.out.println("不能傳送圖片");
}
@Override
void sendText(String to, String message) {
// TODO Auto-generated method stub
System.out.println("普通會員傳送文字");
chatroom.sendText(name, to, message);
}
}
//具體磚石會員
class DiamondMember extends Member{
public DiamondMember(String name) {
super(name);
// TODO Auto-generated constructor stub
}
@Override
void sendImage(String to, String image) {
// TODO Auto-generated method stub
System.out.println("磚石會員傳送圖片");
chatroom.sendImage(name, to, image);
}
@Override
void sendText(String to, String message) {
// TODO Auto-generated method stub
System.out.println("磚石會員傳送文字");
chatroom.sendText(name, to, message);
}
}
六、備忘錄模式。
package BehavioralPatterns.Memento;
/*
* 備忘錄模式(Memento Pattern)儲存一個物件的某個狀態,以便在適當的時候恢復物件。
* 備忘錄模式屬於行為型模式。
* 意圖:在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。
主要解決:所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態,這樣可以在以後將物件恢復到原先儲存的狀態。
何時使用:很多時候我們總是需要記錄一個物件的內部狀態,這樣做的目的就是為了允許使用者取消不確定或者錯誤的操作,能夠恢復到他原先的狀態,使得他有"後悔藥"可吃。
如何解決:通過一個備忘錄類專門儲存物件狀態。
關鍵程式碼:客戶不與備忘錄類耦合,與備忘錄管理類耦合。
應用例項: 1、後悔藥。 2、打遊戲時的存檔。 3、Windows 裡的 ctri + z。 4、IE 中的後退。 4、資料庫的事務管理。
優點: 1、給使用者提供了一種可以恢復狀態的機制,可以使使用者能夠比較方便地回到某個歷史的狀態。 2、實現了資訊的封裝,使得使用者不需要關心狀態的儲存細節。
缺點:消耗資源。如果類的成員變數過多,勢必會佔用比較大的資源,而且每一次儲存都會消耗一定的記憶體。
使用場景: 1、需要儲存/恢復資料的相關狀態場景。 2、提供一個可回滾的操作。
注意事項: 1、為了符合迪米特原則,還要增加一個管理備忘錄的類。 2、為了節約記憶體,可使用原型模式+備忘錄模式。
*/
/*
* 包含角色:
* originator(原發器)
* Memento(備忘錄)
* Caretaker(負責人)
* Emmmmmm
* 這個貌似很簡單
*/
public class Test {
public static void main(String[] args) {
Originator o=new Originator();
CareTaker c=new CareTaker();
o.setState("狀態1");
System.out.println("狀態1:"+o.getState());
c.setMemento(o.creatMemento());
o.setState("狀態2");
System.out.println("狀態2:"+o.getState());
o.restoreMemento(c.getMemento());
System.out.println("從備份返回到狀態1"+o.getState());
}
}
//原發器
class Originator{
private String state;
Originator(){}
//建立一個備忘錄物件
public Memento creatMemento() {
return new Memento(this);
}
//根據備忘錄物件恢復原發器狀態
public void restoreMemento(Memento m) {
state=m.getState();
}
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
//備忘錄
class Memento{
private String state;
public Memento(Originator originator) {
// TODO Auto-generated constructor stub
this.state=originator.getState();
}
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
//負責人
class CareTaker{
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
七、觀察者模式。
package BehavioralPatterns.Observer;
import java.util.ArrayList;
/*
* 觀察者模式(有時又被稱為模型-檢視(View)模式、源-收聽者(Listener)模式或從屬者模式)
* 是軟體設計模式的一種。在此種模式中,
* 一個目標物件管理所有相依於它的觀察者物件,
* 並且在它本身的狀態改變時主動發出通知。
* 這通常透過呼叫各觀察者所提供的方法來實現。
* 此種模式通常被用來實現事件處理系統。
*/
/*
* 包含角色
* Subject(目標)
* ConcreteSubject(具體目標)
* Observer(觀察者)
* ConcreteObserver(具體觀察者)
* Emmmm
* 貌似很簡單的樣子,沒有想象中的那麼複雜
*/
public class Test {
public static void main(String[] args) {
ConcreteObserverA ca=new ConcreteObserverA();
ConcreteObserverB cb=new ConcreteObserverB();
ConcreteSubject s=new ConcreteSubject();
s.attach(ca);
s.attach(cb);
s.cry();
}
}
//抽象目標
abstract class Subject{
protected ArrayList<Observer> observers=new ArrayList<>();
//註冊方法
public void attach(Observer observer) {
observers.add(observer);
}
//登出方法
public void detach(Observer observer) {
observers.remove(observer);
}
public abstract void cry();
}
//抽象觀察者類
interface Observer{
void response();
}
class ConcreteSubject extends Subject{
@Override
public void cry() {
// TODO Auto-generated method stub
System.out.println("發起事件源");
for(Object obs:observers) {
((Observer)obs).response();
}
}
}
class ConcreteObserverA implements Observer{
@Override
public void response() {
// TODO Auto-generated method stub
System.out.println("事件響應A");
}
}
class ConcreteObserverB implements Observer{
@Override
public void response() {
// TODO Auto-generated method stub
System.out.println("事件響應B");
}
}
八、狀態模式。
package BehavioralPatterns.State;
/*
* 狀態模式——允許一個物件在其內部狀態改變時自動改變其行為,物件看起來就像是改變了它的類。
*/
/*
* 包含角色:
* Context(環境類):狀態持有者
* State(抽象狀態類)
* ConcreteState(具體狀態類):從環境類中分離的狀態。
*
* 感覺行為類的模式不假設一些具體的東西,就很難理解
* 假設環境是一個賬號,根據充值金額的數量,有普通,磚石會員的區別
*/
class Test {
public static void main(String[] args) {
Context c=new Context();
c.say();
c.setPrice(5);
c.say();
c.setPrice(11);
c.say();
c.setPrice(12);
c.say();
}
}
/*
* 操作入口,
*/
class Context{
private State state;
private int price;
Context(){
state=new StateA(this);
}
void say(){
state.say();
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
//模擬衝錢
public void setPrice(int price) {
this.price = price;
state.initState(price);
}
public int getPrice() {
return price;
}
}
abstract class State{
protected Context con;
protected int price;
abstract void say();
public State(Context s) {
// TODO Auto-generated constructor stub
this.price=s.getPrice();
con=s;
}
protected void initState(int price) {
if(price>0&&price<10) {
con.setState(new StateB(con));
}else if(price>=10) {
con.setState(new StateC(con));
}else {
con.setState(new StateA(con));
}
}
}
class StateA extends State{
public StateA(Context s) {
super(s);
// TODO Auto-generated constructor stub
}
@Override
void say() {
// TODO Auto-generated method stub
System.out.println("我是普通會員,我充了:"+price);
}
}
class StateB extends State{
public StateB(Context s) {
super(s);
// TODO Auto-generated constructor stub
}
@Override
void say() {
// TODO Auto-generated method stub
System.out.println("我是黃金會員,我充了:"+price);
}
}
class StateC extends State{
public StateC(Context s) {
super(s);
// TODO Auto-generated constructor stub
}
@Override
void say() {
// TODO Auto-generated method stub
System.out.println("我是磚石會員,我充了:"+price);
}
}
九、策略模式。
package BehavioralPatterns.Strategy;
/*
* 在策略模式(Strategy Pattern)中,一個類的行為或其演算法可以在執行時更改。
* 這種型別的設計模式屬於行為型模式。
* 在策略模式中,我們建立表示各種策略的物件和一個行為隨著策略物件改變而改變的 context 物件。
* 策略物件改變 context 物件的執行演算法。
* 類似佈局管理器就是使用的策略模式。
*/
/*
* 包含角色:
* Context(環境類)
* Strategy(抽象策略類)//演算法
* ConcreteStrategy(具體策略類)//具體的演算法
* 假設有加減乘除的幾種演算法
*/
public class Test {
public static void main(String[] args) {
Context c=new Context(new ConcreteStrategyA());
Context c1=new Context(new ConcreteStrategyB());
System.out.println("加法"+c.executIt(5,5));
System.out.println("減法"+c1.executIt(5,5));
}
}
class Context{
private Strategy strategy;
public Context(Strategy strategy) {
// TODO Auto-generated constructor stub
this.strategy=strategy;
}
public int executIt(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
interface Strategy{
public int doOperation(int num1, int num2);
}
class ConcreteStrategyA implements Strategy{
@Override
public int doOperation(int num1, int num2) {
// TODO Auto-generated method stub
return num1+num2;
}
}
class ConcreteStrategyB implements Strategy{
@Override
public int doOperation(int num1, int num2) {
// TODO Auto-generated method stub
return num1-num2;
}
}
十、模板模式。
package BehavioralPatterns.TemplateMethod;
/*
* 在模板模式(Template Pattern)中,
* 一個抽象類公開定義了執行它的方法的方式/模板。
* 它的子類可以按需要重寫方法實現,但呼叫將以抽象類中定義的方式進行。
*/
/*
* 包含角色:
* AbstractClass(抽象類)
* ConcreteClass(具體子類)
* 模擬業務流程什麼的,我覺得來一套軍體拳很好
*/
public class Test {
public static void main(String[] args) {
ConcreteClass c=new ConcreteClass();
c.start();
}
}
abstract class AbstractClass{
abstract void leftHook();
abstract void rightHook();
abstract void end();
public final void start(){
leftHook();
rightHook();
end();
}
}
class ConcreteClass extends AbstractClass{
@Override
void leftHook() {
// TODO Auto-generated method stub
System.out.println("左勾拳");
}
@Override
void rightHook() {
// TODO Auto-generated method stub
System.out.println("右勾拳");
}
@Override
void end() {
// TODO Auto-generated method stub
System.out.println("打完收工");
}
}
十一、訪問者模式。
package BehavioralPatterns.Visitor;
import java.util.ArrayList;
import java.util.Iterator;
/*
* 訪問者模式(Visitor Pattern)是GoF提出的23種設計模式中的一種,屬於行為模式。
* 據《大話設計模式》中說算是最複雜也是最難以理解的一種模式了。
* 定義(源於GoF《Design Pattern》):表示一個作用於某物件結構中的各元素的操作。
* 它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作。
* 從定義可以看出結構物件是使用訪問者模式必備條件,
* 而且這個結構物件必須存在遍歷自身各個物件的方法。這便類似於Java語言當中的collection概念了。
*/
/*
* 包含物件:
* Vistor(抽象訪問模式)
* ConcreteVistor(具體訪問者)
* Element(抽象元素)
* ConcreteElement(具體元素)
* ObjectStructure(物件結構)
* Emmm
* 聽說是 最複雜,最難以理解的模式。
* 不怎麼理解,直接先用書上的例子理一下思路吧
* 訪問者模式例項之購物車
*/
public class Test {
public static void main(String[] args) {
Product p1=new Apple();
Product p2=new Apple();
Product p3=new Book();
Product p4=new Book();
Visitor visitor;
ButBasket basket=new ButBasket();
basket.addProduct(p1);
basket.addProduct(p2);
basket.addProduct(p3);
basket.addProduct(p4);
visitor=new Customer();
visitor.setName("張三");
basket.accept(visitor);
visitor=new Saler();
visitor.setName("張三");
basket.accept(visitor);
}
}
//抽象訪問者
abstract class Visitor{
protected String name;
public void setName(String name) {
this.name = name;
}
public abstract void visit(Apple apple);
public abstract void visit(Book book);
}
//具體訪問者
class Customer extends Visitor{
@Override
public void visit(Apple apple) {
// TODO Auto-generated method stub
System.out.println("顧客"+name+"選蘋果");
}
@Override
public void visit(Book book) {
// TODO Auto-generated method stub
System.out.println("顧客"+name+"買書");
}
}
//具體訪問者
class Saler extends Visitor{
@Override
public void visit(Apple apple) {
// TODO Auto-generated method stub
System.out.println("收銀員"+name+"給蘋果過秤,然後計算其價格。");
}
@Override
public void visit(Book book) {
// TODO Auto-generated method stub
System.out.println("收銀員"+name+"直接計算書的價格");
}
}
//抽象產品
interface Product{
void accept(Visitor vistor);
}
//具體產品
class Apple implements Product{
@Override
public void accept(Visitor vistor) {
// TODO Auto-generated method stub
vistor.visit(this);
}
}
//具體產品
class Book implements Product{
@Override
public void accept(Visitor vistor) {
// TODO Auto-generated method stub
vistor.visit(this);
}
}
//物件結構
class ButBasket{
private ArrayList<Product> list=new ArrayList<>();
public void accept(Visitor visitor) {
Iterator<Product> i=list.iterator();
while (i.hasNext()) {
i.next().accept(visitor);
}
}
public void addProduct(Product product) {
list.add(product);
}
public void removeProduct(Product product) {
list.remove(product);
}
}
參考資料:
《設計模式》 劉偉主編
菜鳥教程 :http://www.runoob.com/
百度百科