掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流
允許一個(gè)對(duì)象在其內(nèi)部改變時(shí)改變它的行為

目前創(chuàng)新互聯(lián)建站已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、雅安服務(wù)器托管、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、右玉網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶(hù)導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶(hù)和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
狀態(tài)變成類(lèi)
狀態(tài)模式主要用來(lái)解決對(duì)象在多種狀態(tài)轉(zhuǎn)換時(shí),需要對(duì)外輸出不同的行為的問(wèn)題。比如訂單從待付款到待收貨的咋黃臺(tái)發(fā)生變化,執(zhí)行的邏輯是不一樣的。
所以我們將狀態(tài)抽象為一個(gè)接口或者抽象類(lèi),對(duì)不同狀態(tài)進(jìn)行封裝成單獨(dú)的實(shí)體,用于實(shí)現(xiàn)各種狀態(tài)處理的邏輯。
再設(shè)計(jì)一個(gè)上下文類(lèi),它組合了狀態(tài)接口,用于發(fā)送請(qǐng)求。針對(duì)不同的狀態(tài)提供不同的處理方法即可。
/**
* 狀態(tài)接口 提供處理狀態(tài)的方法
*/
public interface IState {
// 處理狀態(tài),交給實(shí)現(xiàn)類(lèi)實(shí)現(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)上下文類(lèi)
*/
public class Context {
// 組合訂單狀態(tài)
private final IState state;
public Context(IState state) {
this.state = state;
}
// 提供處理訂單方法
public void handleOrderByState(){
state.handleState();
}
}
/**
* 測(cè)試類(lèi)
*/
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();
}
}
其實(shí)我們可以看出來(lái),狀態(tài)模式和策略模式非常像,都有一個(gè)Context類(lèi),都有一個(gè)接口或抽象類(lèi)被Context組合。而后抽象類(lèi)或接口有自己的不同實(shí)現(xiàn)。
它們確實(shí)很像,但是它們確實(shí)有區(qū)別,因?yàn)闋顟B(tài)模式圍繞著狀態(tài)的變化,它的子類(lèi)之間的狀態(tài)是可以進(jìn)行轉(zhuǎn)換的,比如訂單狀態(tài)由未付款變?yōu)橐迅犊?。但是策略模式則不會(huì),只會(huì)二者取其一,進(jìn)行一種策略操作。
表示一個(gè)作用域某對(duì)象結(jié)構(gòu)中的個(gè)元素的操作,使得在不改變各元素的前提下定義作用域這些元素的新操作。
數(shù)據(jù)與操作分離
/**
* 定義被訪(fǎng)問(wèn)接口
*/
public interface Person {
// 提供一個(gè)方法,讓訪(fǎng)問(wèn)者可以訪(fǎng)問(wèn)
void accept(Action action);
}
/**
* 訪(fǎng)問(wèn)者,這里提供了多個(gè)訪(fǎng)問(wèn)方法,從而獲取多個(gè)不同的訪(fǎng)問(wèn)結(jié)果,它們的參數(shù)分別對(duì)應(yīng)具體的被訪(fǎng)問(wèn)元素
*/
public interface Action {
// 得到男性 的測(cè)評(píng)
void getManResult(Man man);
// 得到女的 測(cè)評(píng)
void getWomanResult(Woman woman);
}
/**
* 被訪(fǎng)問(wèn)者元素男人實(shí)現(xiàn),傳入自己給訪(fǎng)問(wèn)者訪(fǎng)問(wèn)
*/
public class Man implements Person{
@Override
public void accept(Action action) {
action.getManResult(this);
}
}
/**
* 被訪(fǎng)問(wèn)者元素女人實(shí)現(xiàn),傳入自己給訪(fǎng)問(wèn)者訪(fǎng)問(wèn)
*/
public class Woman implements Person{
@Override
public void accept(Action action) {
action.getWomanResult(this);
}
}
/**
* 訪(fǎng)問(wèn)者實(shí)現(xiàn)類(lèi) 對(duì)不同的被訪(fǎng)問(wèn)元素做不同的訪(fǎng)問(wèn)
*/
class Success implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人給的評(píng)價(jià): 歌手很表演很nice");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("女人給的評(píng)價(jià): 歌手很表演很nice");
}
}
class Normal implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人給的評(píng)價(jià)是: 歌手很表演比較普通");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("女人給的評(píng)價(jià)是: 歌手很表演比較普通");
}
}
public class Fail implements Action {
@Override
public void getManResult(Man man) {
System.out.println("男人給的評(píng)價(jià): 歌手很表演有點(diǎn)糟糕");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("女人給的評(píng)價(jià): 歌手很表演有點(diǎn)糟糕");
}
}
/**
* 數(shù)據(jù)結(jié)構(gòu),管理很多人(Man , Woman)
*/
class ObjectStructure {
//維護(hù)了一個(gè)集合
private Listpersons = new LinkedList<>();
//添加
public void add(Person p) {
persons.add(p);
}
//刪除
public void delete(Person p) {
persons.remove(p);
}
// 顯示測(cè)評(píng)情況(便利)
public void show(Action action) {
for (Person p : persons) {
p.accept(action);
}
}
}
/**
* 測(cè)試類(lèi)
*/
public class Client {
public static void main(String[] args) {
// 使用數(shù)據(jù)結(jié)構(gòu)來(lái)創(chuàng)建
ObjectStructure os = new ObjectStructure();
// 添加我們我們的訪(fǎng)問(wèn)者
os.add(new Man());
os.add(new Woman());
// 創(chuàng)建成功的被訪(fǎng)問(wèn)者
Success success = new Success();
// 通過(guò)數(shù)據(jù)結(jié)果遍歷訪(fǎng)問(wèn)者,然后進(jìn)行訪(fǎng)問(wèn)成功的數(shù)據(jù)
os.show(success);
System.out.println("========================");
// 創(chuàng)建失敗的被訪(fǎng)問(wèn)者
Fail fail = new Fail();
// 通過(guò)數(shù)據(jù)結(jié)果遍歷訪(fǎng)問(wèn)者,然后進(jìn)行訪(fǎng)問(wèn)失敗的數(shù)據(jù)
os.show(fail);
System.out.println("========================");
// 創(chuàng)建中肯的的被訪(fǎng)問(wèn)者
Normal normal = new Normal();
os.show(normal);
}
}
其實(shí)訪(fǎng)問(wèn)者模式和觀察者模式的思想也非常類(lèi)似,代碼實(shí)現(xiàn)也很類(lèi)似。都會(huì)提供一個(gè)管理被訪(fǎng)問(wèn)者/觀察者集合,提供新增和刪除方法,并且提供一個(gè)遍歷集合的方法,并通知所有元素或者指定元素的方法。
它們只是應(yīng)用場(chǎng)景不一樣,其實(shí)類(lèi)圖都很類(lèi)似。
其實(shí)我們可以看出,狀態(tài)模式和策略模式很類(lèi)似,簡(jiǎn)直就是親兄弟一樣。而訪(fǎng)問(wèn)者模式其實(shí)和觀察者模式也很類(lèi)似。所以我們的設(shè)計(jì)模式設(shè)計(jì)到最后,可能就會(huì)存在一種模式里有另一種模式的影子。所以我們要搞清楚它們之間的區(qū)別。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢(xún)/運(yùn)營(yíng)咨詢(xún)/技術(shù)建議/互聯(lián)網(wǎng)交流