自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

架構(gòu)師備戰(zhàn)軟件工程之行為型設(shè)計模式

開發(fā) 前端
狀態(tài)模式和策略模式很類似,簡直就是親兄弟一樣。而訪問者模式其實和觀察者模式也很類似。所以我們的設(shè)計模式設(shè)計到最后,可能就會存在一種模式里有另一種模式的影子。所以我們要搞清楚它們之間的區(qū)別。

1、狀態(tài)模式

簡要說明

允許一個對象在其內(nèi)部改變時改變它的行為

速記關(guān)鍵字

狀態(tài)變成類

類圖如下

狀態(tài)模式主要用來解決對象在多種狀態(tài)轉(zhuǎn)換時,需要對外輸出不同的行為的問題。比如訂單從待付款到待收貨的咋黃臺發(fā)生變化,執(zhí)行的邏輯是不一樣的。

所以我們將狀態(tài)抽象為一個接口或者抽象類,對不同狀態(tài)進行封裝成單獨的實體,用于實現(xiàn)各種狀態(tài)處理的邏輯。

再設(shè)計一個上下文類,它組合了狀態(tài)接口,用于發(fā)送請求。針對不同的狀態(tài)提供不同的處理方法即可。

Java代碼實現(xiàn)

/**
* 狀態(tài)接口 提供處理狀態(tài)的方法
*/
public interface IState {

// 處理狀態(tài),交給實現(xiàn)類實現(xiàn)
void handleState();
}

/**
* 未付款狀態(tài)
*/
public class UnpaidState implements IState{
@Override
public void handleState() {
System.out.println("下單成功,訂單狀態(tài)為待付款");
}
}

/**
* 已付款狀態(tài)
*/
public class PaidState implements IState{
@Override
public void handleState() {
System.out.println("支付成功,訂單狀態(tài)為已付款");
}
}

/**
* 已取消狀態(tài)
*/
public class CancelState implements IState{
@Override
public void handleState() {
System.out.println("訂單取消支付,訂單狀態(tài)為已取消");
}
}

/**
* 訂單狀態(tài)上下文類
*/
public class Context {
// 組合訂單狀態(tài)
private final IState state;

public Context(IState state) {
this.state = state;
}

// 提供處理訂單方法
public void handleOrderByState(){
state.handleState();
}
}

/**
* 測試類
*/
public class Client {
public static void main(String[] args) {
// 創(chuàng)建上下文并創(chuàng)建未支付狀態(tài)
Context context = new Context(new UnpaidState());
context.handleOrderByState();

// 創(chuàng)建上下文并創(chuàng)建已支付狀態(tài)
Context context2 = new Context(new PaidState());
context2.handleOrderByState();
}
}

結(jié)果輸出

其實我們可以看出來,狀態(tài)模式和策略模式非常像,都有一個Context類,都有一個接口或抽象類被Context組合。而后抽象類或接口有自己的不同實現(xiàn)。

它們確實很像,但是它們確實有區(qū)別,因為狀態(tài)模式圍繞著狀態(tài)的變化,它的子類之間的狀態(tài)是可以進行轉(zhuǎn)換的,比如訂單狀態(tài)由未付款變?yōu)橐迅犊睢5遣呗阅J絼t不會,只會二者取其一,進行一種策略操作。

2、訪問者模式

簡要說明

表示一個作用域某對象結(jié)構(gòu)中的個元素的操作,使得在不改變各元素的前提下定義作用域這些元素的新操作。

速記關(guān)鍵字

數(shù)據(jù)與操作分離

類圖如下

角色說明

  • Visitor(抽象訪問者):為每種具體的被訪問者(ConcreteElement)聲明一個訪問操作
  • ConcreteVisitor(具體訪問者):實現(xiàn)對被訪問者(ConcreteElement)的具體訪問操作,所以需要組合多個元素,也就是組合一組元素集合
  • Element(抽象被訪問者):通常有一個Accept方法,用來接收/引用一個抽象訪問者對象(基本原理)
  • ConcreteElement(具體被訪問者對象):實現(xiàn)Accept抽象方法,通過傳入的具體訪問者參數(shù)、調(diào)用具體訪問者對該對象的訪問操作方法實現(xiàn)訪問邏輯
  • Clent、ObjectStructure(客戶端訪問過程測試環(huán)境):該過程中,被訪問者通常為一個集合對象,通過對集合的遍歷完成訪問者對每一個被訪問元素的訪問操作;

Java代碼實現(xiàn)

/**
* 定義被訪問接口
*/
public interface Person {
// 提供一個方法,讓訪問者可以訪問
void accept(Action action);
}

/**
* 訪問者,這里提供了多個訪問方法,從而獲取多個不同的訪問結(jié)果,它們的參數(shù)分別對應(yīng)具體的被訪問元素
*/
public interface Action {
// 得到男性 的測評
void getManResult(Man man);

// 得到女的 測評
void getWomanResult(Woman woman);
}

/**
* 被訪問者元素男人實現(xiàn),傳入自己給訪問者訪問
*/
public class Man implements Person{
@Override
public void accept(Action action) {
action.getManResult(this);
}
}

/**
* 被訪問者元素女人實現(xiàn),傳入自己給訪問者訪問
*/
public class Woman implements Person{
@Override
public void accept(Action action) {
action.getWomanResult(this);
}
}

/**
* 訪問者實現(xiàn)類 對不同的被訪問元素做不同的訪問
*/
class Success implements Action {

@Override
public void getManResult(Man man) {
System.out.println("男人給的評價: 歌手很表演很nice");
}

@Override
public void getWomanResult(Woman woman) {
System.out.println("女人給的評價: 歌手很表演很nice");
}
}

class Normal implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人給的評價是: 歌手很表演比較普通");
}

@Override
public void getWomanResult(Woman woman) {
System.out.println("女人給的評價是: 歌手很表演比較普通");
}
}

public class Fail implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人給的評價: 歌手很表演有點糟糕");
}

@Override
public void getWomanResult(Woman woman) {
System.out.println("女人給的評價: 歌手很表演有點糟糕");
}
}

/**
* 數(shù)據(jù)結(jié)構(gòu),管理很多人(Man , Woman)
*/
class ObjectStructure {
//維護了一個集合
private List<Person> persons = new LinkedList<>();

//添加
public void add(Person p) {
persons.add(p);
}

//刪除
public void delete(Person p) {
persons.remove(p);
}

// 顯示測評情況(便利)
public void show(Action action) {
for (Person p : persons) {
p.accept(action);
}
}
}

/**
* 測試類
*/
public class Client {
public static void main(String[] args) {
// 使用數(shù)據(jù)結(jié)構(gòu)來創(chuàng)建
ObjectStructure os = new ObjectStructure();
// 添加我們我們的訪問者
os.add(new Man());
os.add(new Woman());


// 創(chuàng)建成功的被訪問者
Success success = new Success();
// 通過數(shù)據(jù)結(jié)果遍歷訪問者,然后進行訪問成功的數(shù)據(jù)
os.show(success);
System.out.println("========================");

// 創(chuàng)建失敗的被訪問者
Fail fail = new Fail();
// 通過數(shù)據(jù)結(jié)果遍歷訪問者,然后進行訪問失敗的數(shù)據(jù)
os.show(fail);
System.out.println("========================");

// 創(chuàng)建中肯的的被訪問者
Normal normal = new Normal();
os.show(normal);
}
}

其實訪問者模式和觀察者模式的思想也非常類似,代碼實現(xiàn)也很類似。都會提供一個管理被訪問者/觀察者集合,提供新增和刪除方法,并且提供一個遍歷集合的方法,并通知所有元素或者指定元素的方法。

它們只是應(yīng)用場景不一樣,其實類圖都很類似。

結(jié)果輸出

3、小結(jié)

其實我們可以看出,狀態(tài)模式和策略模式很類似,簡直就是親兄弟一樣。而訪問者模式其實和觀察者模式也很類似。所以我們的設(shè)計模式設(shè)計到最后,可能就會存在一種模式里有另一種模式的影子。所以我們要搞清楚它們之間的區(qū)別。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2011-10-10 10:10:14

2009-11-04 10:57:35

2011-08-30 10:03:59

軟件工程

2022-11-09 07:18:18

驅(qū)動測試BDD

2012-12-13 09:47:15

軟件架構(gòu)師架構(gòu)師

2011-04-07 16:20:24

軟件架構(gòu)師架構(gòu)師架構(gòu)

2022-01-16 07:12:30

軟件工程師吵架開發(fā)

2022-10-19 15:34:11

架構(gòu)軟件安全

2023-06-05 10:07:13

軟件工程平臺工程師

2023-10-23 11:49:59

2020-08-28 13:20:53

谷歌Android開發(fā)者

2009-02-11 13:15:54

軟件工程師女工程師google

2021-10-22 08:00:00

架構(gòu)開發(fā)技術(shù)

2009-02-12 14:45:17

軟件工程師

2013-09-03 09:30:44

軟件工程師軟件工程師頭銜

2014-08-20 10:24:11

軟件工程師

2010-08-10 13:29:58

軟件工程師

2022-09-16 08:00:00

軟件工程師求職薪酬

2022-04-18 10:13:32

軟件開發(fā)寫作

2022-07-29 09:12:44

軟件硬件開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號