成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

如何使用行為型模式

本篇內(nèi)容介紹了“如何使用行為型模式”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名申請、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、札達(dá)網(wǎng)站維護(hù)、網(wǎng)站推廣。

狀態(tài)模式

狀態(tài)模式的好處是將與特定狀態(tài)相關(guān)的行為局部化,并且將不同狀態(tài)的行為分割開來

將特定相關(guān)的行為都放入一個對象中,由于所有與狀態(tài)相關(guān)的代碼都存在于某個ConcreteState 中,所以通過定義新的子類可以很容易地增加新的狀態(tài)和轉(zhuǎn)換。

Context:上下文,定義了客戶程序需要的接口并維護(hù)一個狀態(tài)類。

State:狀態(tài)類,定義一個接口以封裝上下文環(huán)境的一個特定狀態(tài)相關(guān)的行為,與狀態(tài)相關(guān)的操作委托給具體的state對象進(jìn)行處理。

Concrete State:具體狀態(tài)類

狀態(tài)模式UML

如何使用行為型模式

采用的例子是王者里面的,要么在打團(tuán)要么在打團(tuán)的路上,這就涉及到了狀態(tài)的轉(zhuǎn)換。

如何使用行為型模式

狀態(tài)模式

State

public interface State {
    void handle(Context context);
}

Concrete State

回城狀態(tài)

public class ConcreteStateBack implements State{
    @Override
    public void handle(Context context) {
        System.out.println("沒狀態(tài)了,回城補(bǔ)個狀態(tài)先");
        context.setState(new ConcreteStateWalk());
    }
}

打團(tuán)狀態(tài)

public class ConcreteStateFight implements State{
    @Override
    public void handle(Context context) {
        System.out.println("大招一按,蒼穹一開,雙手一放,要么黑屏,要么五殺");
        context.setState(new ConcreteStateBack());
    }
}

打團(tuán)的路上狀態(tài)

public class ConcreteStateWalk implements State{
    @Override
    public void handle(Context context) {
        System.out.println("狀態(tài)已滿,等我集合打團(tuán)");
        context.setState(new ConcreteStateFight());
    }
}

失敗狀態(tài)

public class ConcreteStateDefeated implements State{
    @Override
    public void handle(Context context) {
        System.out.println("Defeated!!!");
    }
}

Context

public class Context {
    private State state;

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

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

    public void request() {
        state.handle(this);
    }
}

Client

public class Client {
    public static void main(String[] args) {
        Context context = new Context(new ConcreteStateWalk());
        for (int i = 0; i < 8; i++) {
            context.request();
        }

        context.setState(new ConcreteStateDefeated());
        context.request();

    }
}

策略模式

策略模式是一種定義一系列算法的方法,但是這些方法最終完成的都是相同的工作,只是策略不同,也就是實(shí)現(xiàn)不同。

它可以以相同的方式來調(diào)用所有的算法,減少了各種算法類和使用算法類之間的耦合。

Context:上下文,內(nèi)部有個strategy屬性,并且能夠通過其調(diào)用策略

Strategy:策略接口或者抽象類,定義了策略的方法

Concrete Strategy:具體的策略

狀態(tài)模式UML

如何使用行為型模式

狀態(tài)模式

還是拿游戲舉例,最終的目的都是為了贏,但是具體的方式可能要根據(jù)對方的陣容做出改變。

如何使用行為型模式

Context

public class Context {
    Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void invokeStrategy() {
        strategy.play();
    }
}

Strategy

public interface Strategy {
    void play();
}

Concrete Strategy

public class ConcreteStrategyAttackMid implements Strategy{
    @Override
    public void play() {
        System.out.println("集合進(jìn)攻中路");
    }
}
public class ConcreteStrategyGank implements Strategy{
    @Override
    public void play() {
        System.out.println("轉(zhuǎn)線抓人推塔");
    }
}
public class ConcreteStrategyInvade implements Strategy{
    @Override
    public void play() {
        System.out.println("入侵野區(qū)");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        Context context = new Context(new ConcreteStrategyAttackMid());
        context.invokeStrategy();

        context = new Context(new ConcreteStrategyGank());
        context.invokeStrategy();

        context = new Context(new ConcreteStrategyInvade());
        context.invokeStrategy();
    }
}

模板方法模式

模板方法就是定義一個操作的算法的骨架,而將一些步驟延遲到子類種。模板方法使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義改算法的某些特定步驟。

簡而言之就是,我給你一個模板,步驟是哪些,但是具體怎么實(shí)現(xiàn)看個人。

Abstract Class:實(shí)現(xiàn)一個模板方法,定義了算法的估計

Concrete Class:對模板中各個算法的不同實(shí)現(xiàn)

模板方法UML

如何使用行為型模式

模板方法

都知道電腦的組裝都是有一個模板的,需要哪些零件都是固定的,不同的是零件的采用不同。這樣我們就可以把組裝作為一個行為模板給封裝起來。

Abstract Class

public abstract class AbstractClass {
    public void assemble() {
        System.out.println("開始模板組裝電腦");
        cpu();
        radiating();
        screen();
    }

    public abstract void cpu();
    public abstract void radiating();
    public abstract void screen();
}

Concrete Class

public class ConcreteClassMid extends AbstractClass{
    @Override
    public void cpu() {
        System.out.println("Intel 10900K, Intel偶爾的神");
    }

    @Override
    public void radiating() {
        System.out.println("雙銅散熱管");
    }

    @Override
    public void screen() {
        System.out.println("75hz高素質(zhì)屏幕");
    }
}

如何使用行為型模式

public class ConcreteClassTop extends AbstractClass{
    @Override
    public void cpu() {
        System.out.println("AMD5950X,AMD永遠(yuǎn)的神");
    }

    @Override
    public void radiating() {
        System.out.println("雙銅散熱管加液冷散熱");
    }

    @Override
    public void screen() {
        System.out.println("144hz電競屏");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        AbstractClass templateToAssembleComputer = new ConcreteClassMid();
        templateToAssembleComputer.assemble();

        templateToAssembleComputer = new ConcreteClassTop();
        templateToAssembleComputer.assemble();
    }
}

到這里有沒有印象之前說過的建造者模式,可以說非常相似,因為建造者模式就是借助了模板方法模式來實(shí)現(xiàn)的。

如何使用行為型模式

備忘錄模式

在不破壞封裝的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài),這樣可以在以后將對象恢復(fù)到原先保存的狀態(tài)。備忘錄嘛,也是比較形象的,就像我們解題的時候可以把過程寫下來看,最后可以按照步驟檢查,知道哪里出了問題,從那里恢復(fù)解題的過程,從而正確解題。

Originator:發(fā)起者是我們需要記住狀態(tài)的對象,以便在某個時刻恢復(fù)它。

Caretaker:管理者是負(fù)責(zé)觸發(fā)發(fā)起者的變化或者觸發(fā)發(fā)起者返回先前狀態(tài)動作的類。

Memento:備忘錄是負(fù)責(zé)存儲發(fā)起者內(nèi)部狀態(tài)的類。備忘錄提供了設(shè)置狀態(tài)和獲取狀態(tài)的方法,但是這些方法應(yīng)該對管理者隱藏。

**場景:**大家都玩過超級瑪麗,合金彈頭,或者i wanna這類的游戲叭。有什么組成呢,一個是玩家(Originator),一個是經(jīng)常需要存檔的檔案(Memento),還有一個是游戲后臺管理(Caretaker)。

對于玩家而言,可以存檔(setMemento和createMemento),也可以讀檔,恢復(fù)到上次存檔的位置(restoreMemento)。

備忘錄UML

如何使用行為型模式

普通備忘錄模式:

Originator (玩家)

public class OriginatorPlayer {
    private String name;
    private String status;

    public OriginatorPlayer(String name) {
        this.name = name;
    }

    //交給游戲后臺處理    1
    public MementoGameState create() {
        return new MementoGameState(status);
    }

    //玩家存檔           2
    public void save(String status) {
        this.status = status;
        System.out.println("存檔:" + status);
    }

    public void read(MementoGameState gameState) {
        this.status = gameState.getGameStatus();
        System.out.println("讀檔:" + status);
    }

}

其實(shí)我覺得1,2步是可以合起來寫成下面這樣子

public MementoGameState save(String status) {
    this.status = status;
    System.out.println("存檔:" + status);
    return new MementoGameState(status);
}

Memento (游戲狀態(tài))

public class MementoGameState {
    private String gameStatus = "";

    public MementoGameState(String gameStatus) {
        this.gameStatus = gameStatus;
    }

    public String getGameStatus() {
        return gameStatus;
    }

}

Caretaker (后臺管理)

public class CaretakerGameManager {
    MementoGameState gameState;
    
    public MementoGameState getGameState() {
        return gameState;
    }

    //這是后臺真正存檔
    public void setGameState(MementoGameState gameState) {
        System.out.println("系統(tǒng)已經(jīng)存檔: " + gameState.getGameStatus());
        this.gameState = gameState;
    }
}

Client

public class Client {
    public static void main(String[] args) {
        OriginatorPlayer cutey = new OriginatorPlayer("cutey");
        CaretakerGameManager gameManager = new CaretakerGameManager();

        //玩家自己點(diǎn)了存檔,但是不一定存成功
        cutey.save("第一關(guān)");
        //后臺要處理玩家的存檔的請求(imperfect.create())
        gameManager.setGameState(cutey.create());

        cutey.save("第二關(guān)");
        gameManager.setGameState(cutey.create());

        //這種情況就是可能我們點(diǎn)了存檔,還沒有成功就退出了
        cutey.save("第三關(guān)");

        //讀取檔案
        cutey.read(gameManager.getGameState());
    }
}

仔細(xì)地看代碼會發(fā)現(xiàn),說到底講備忘錄,備忘的是不是就是游戲角色的狀態(tài),為此專門有一個類(GameState)來存這個狀態(tài)。

在恢復(fù)狀態(tài)的時候,在讀取備忘錄中的狀態(tài)賦給游戲角色中。所以歸根結(jié)底都是如何保存游戲角色的狀態(tài),然后在需要的時候可以恢復(fù)。

那是不是一定要新建一個類來幫我們保存呢,如果我們直接保存的是上個階段的游戲角色(而不是單純的游戲狀態(tài)),然后讀檔的時候直接讀上個階段的游戲角色可以嗎?

也就是發(fā)起人(Originator)也充當(dāng)了備忘錄(Memento)肯定是可以的。

又來想,要存的是自己,要拷貝的是自己來充當(dāng)備忘錄,為了節(jié)省空間,會用到之后講的原型模式

如何使用行為型模式

到這里的話,普通的備忘錄模式就已經(jīng)講完了,下面要講的都是基于普通上進(jìn)行的改進(jìn),可看可不看。

基于clone的備忘錄模式:

玩家:

public class PlayerC implements Cloneable {
	
    private String name;
    private String state;

    public PlayerC(String name) {
        this.name = name;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        System.out.println("玩家進(jìn)行到:" + state);
        this.state = state;
    }


    //存檔,存的是自己
    public PlayerC create() {
        System.out.println("玩家存檔:" + this.clone().getState());
        return this.clone();
    }

    
    //讀檔
    public void play(PlayerC playerC) {
        System.out.println("玩家讀檔:" + playerC.getState());
        setState(playerC.getState());
    }
    
    //克隆自己
    @Override
    public PlayerC clone() {
        try {
            return (PlayerC) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }

}

后臺管理:

public class GameManagerC {
    PlayerC playerC;

    public PlayerC getPlayerC() {
        return playerC;
    }

    //真正的存檔
    public void setPlayerC(PlayerC playerC) {
        this.playerC = playerC;
    }
}

Client:

public class ClientC {
    public static void main(String[] args) throws CloneNotSupportedException {
        PlayerC playerC = new PlayerC("perfext");
        GameManagerC gameManagerC = new GameManagerC();

        //分析和普通模式一樣,就不再贅述
        playerC.setState("%10");
        gameManagerC.setPlayerC(playerC.create());

        playerC.setState("%20");
        gameManagerC.setPlayerC(playerC.create());

        playerC.setState("%30");

        playerC.play(gameManagerC.getPlayerC());

    }
}

上面甚至還不是最簡潔的,因為其實(shí)我們存檔還是要在后臺管理類里面存,當(dāng)然這是希望看到的。想想后臺管理類的作用是干嘛的,是用來管理備忘錄的,既然備忘錄類都可以省略,后臺管理類自然也可以精簡掉。

也就是說,玩家的狀態(tài)保存在玩家的內(nèi)部,但是這與定義不符合,在一開始我特意加粗了”在該對象之外保存這個狀態(tài)“。所以說本篇博客就不再講述這種方式的實(shí)現(xiàn),也比較簡單(提示:在玩家類內(nèi)部聲明一個成員變量作為恢復(fù)的游戲角色)。

上面講的都是比較簡單的備忘錄模式,還有兩種比較常用的,一種是一個角色有多個狀態(tài)同時需要備忘,先講這種,另外一種賣個關(guān)子。

多狀態(tài)的備忘錄模式:

場景:一個角色有多個狀態(tài),那還是拿打游戲的例子,不過游戲角色不僅僅是第幾關(guān)。新的游戲角色有,打到了哪個階段,等級是多少以及裝備三個狀態(tài)。

玩家:

public class PlayerS {
    private String name;
    private String equipment;
    private String schedule;
    private String grade;

    //存檔
    public GameStateS save() {
        System.out.println("玩家存檔:" + toString());
        return new GameStateS(this);
    }

    //讀檔案,從保存的狀態(tài)中一個個讀出來
    public void read(GameStateS gameStateS) {
        equipment = (String) gameStateS.getStates().get("equipment");
        schedule = (String) gameStateS.getStates().get("schedule");
        grade = (String) gameStateS.getStates().get("grade");
        System.out.println("玩家讀檔:" + toString());
    }

    public PlayerS(String name) {
        this.name = name;
    }

    /**
     *  省略
     *	1.toString方法,用來方便打印
     * 	2.set方法,用來方便玩家存檔
     *	3.get方法,方便存儲玩家的狀態(tài)
     */
    
}

游戲狀態(tài)(檔案):

public class GameStateS {
    //多狀態(tài),所以用hashmap來保存
    private HashMap<String, Object> states = new HashMap<>();

    //保存著玩家的狀態(tài)
    public GameStateS(PlayerS playerS) {
        states.put("schedule", playerS.getSchedule());
        states.put("grade", playerS.getGrade());
        states.put("equipment", playerS.getEquipment());
    }

    public HashMap<String, Object> getStates() {
        return states;
    }

}

后臺管理:

public class GameManagerS {
    private GameStateS gameStateS;

    public GameStateS getGameStateS() {
        return gameStateS;
    }

    //真正存檔
    public void setGameStateS(GameStateS gameStateS) {
        System.out.println("系統(tǒng)已經(jīng)存檔!");
        this.gameStateS = gameStateS;
    }
}

Client:

public class ClientS {

    public static void main(String[] args) {
        PlayerS player = new PlayerS("perfext");
        GameManagerS gameManagerS = new GameManagerS();

        player.setSchedule("10%");
        player.setEquipment("2件套");
        player.setGrade("6級");
        gameManagerS.setGameStateS(player.save());

        player.setSchedule("30%");
        player.setEquipment("4件套");
        player.setGrade("10級");
        gameManagerS.setGameStateS(player.save());

        player.setSchedule("80%");
        player.setEquipment("6件套");
        player.setGrade("15級");
        System.out.println("忘記存檔了!已經(jīng)打到了:");
        System.out.println(player.toString());

        player.read(gameManagerS.getGameStateS());
    }

}

本質(zhì)還是那樣,沒有太大變化,就是把狀態(tài)用hashmap做了一個封裝。

目前為止,對于上面所講的所有備忘錄模式,不知道各位小伙伴有沒有發(fā)現(xiàn)一個問題,就是在恢復(fù)的時候,只能恢復(fù)特定的狀態(tài)(一般是最后備忘的那個狀態(tài))。

但是在現(xiàn)實(shí)社會中,在碼字或者打代碼的時候總你能夠ctrl + z(撤銷)好幾次,可以撤銷回滿意的狀態(tài)。下面要講的應(yīng)該可以幫助到你。

撤銷多次的備忘錄模式:

原諒我不知道怎么高大上專業(yè)的表述這種備忘錄模式。

**場景:**再用游戲講的話不太清楚,接下來打字員(Originator)打字,內(nèi)容(Memento)交給電腦(Caretaker)保存來演示。

打字員:

public class Typist {
    private String name;
    private String word;	//最新的狀態(tài)
    private List<String> content = new ArrayList<>();		//所有的狀態(tài)
    int len = 0;	//狀態(tài)的位置,根據(jù)這個位置來讀取

    public Typist(String name) {
        this.name = name;
    }

    public void setWord(String word) {
        this.word = word;
    }

    //保存
    public TypeContent save() {
        content.add(word);
        System.out.println("打字員保存:" + word);
        len++;		//長度+1
        return new TypeContent(content);
    }

    //讀取
    public void read(TypeContent typeContent) {
        content = typeContent.getTypeContent();
        System.out.println("目前顯示:" + content.get(--len));	//讀完后長度-1
    }

}

內(nèi)容:

public class TypeContent {
    private List<String> typeContent = new ArrayList<>();

    //保存用戶寫的字
    public TypeContent(List<String> typeContent) {
        this.typeContent = typeContent;
    }

    public List<String> getTypeContent() {
        return typeContent;
    }

}

電腦:

public class Computer {
    private TypeContent typeContent;

    public TypeContent getTypeContent() {
        return typeContent;
    }

    //真正保存用戶寫的字
    public void setTypeContent(TypeContent typeContent) {
        this.typeContent = typeContent;
    }
}

Client:

public class ClientM {
    public static void main(String[] args) {
        Typist perfext = new Typist("perfext");
        Computer computer = new Computer();

        perfext.setWord("abcd");
        computer.setTypeContent(perfext.save());
        perfext.setWord("efg");
        computer.setTypeContent(perfext.save());
        perfext.setWord("hijkl");
        computer.setTypeContent(perfext.save());
        perfext.setWord("mnopq");
        computer.setTypeContent(perfext.save());

        perfext.read(computer.getTypeContent());
        
        //模擬ctrl+z
        System.out.println("撤銷:");
        perfext.read(computer.getTypeContent());
        
        System.out.println("撤銷:");
        perfext.read(computer.getTypeContent());
        
        System.out.println("撤銷:");
        perfext.read(computer.getTypeContent());

    }
}

“如何使用行為型模式”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

網(wǎng)頁題目:如何使用行為型模式
分享網(wǎng)址:http://jinyejixie.com/article4/ppehoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站品牌網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、Google、手機(jī)網(wǎng)站建設(shè)、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
积石山| 古田县| 天长市| 高平市| 双流县| 凤凰县| 伊吾县| 杨浦区| 罗城| 洛浦县| 抚远县| 班戈县| 南华县| 濮阳县| 依兰县| 白水县| 黄石市| 依安县| 神木县| 兴城市| 钟山县| 方山县| 梅州市| 布尔津县| 浮山县| 南川市| 勃利县| 洞头县| 绵竹市| 玉溪市| 离岛区| 察隅县| 宣化县| 杭锦后旗| 龙里县| 大港区| 门头沟区| 桦南县| 庆城县| 普宁市| 缙云县|