Android 幾種行爲型設計模式

目錄

6.策略模式

7.狀態模式

8.責任鏈模式

9.解釋器模式 (略)

10.命令模式


6.策略模式

//業務 : 梨子1單位2塊錢 橙子1單位5 蘋果1單位8000 計算價格

//價格計算類
public class PriceCalculator {

    private static final int PEAR = 1;
    private static final int ORANGE = 2;
    private static final int APPLE = 3;

    /**
     * @param number 數量
     * @return 數量*單價 = 總價
     */
    private static int pearPrice(int number) {
        return number * 2;
    }

    private static int orangePrice(int number) {
        return number * 5;
    }

    private static int applePrice(int number) {
        return number * 8000;
    }

    public static int calculatePrice(int number, int type) {
        switch (type) {
            case PEAR:
                return pearPrice(number);
            case ORANGE:
                return orangePrice(number);
            case APPLE:
                return applePrice(number);
            default:
                return -1;
        }
    }
}

//使用:計算10個梨子的價格
PrceCalculator.calculatePrice(10,PriceCalculator.PEAR);

//分析:PriceCalculator類同時承擔了計算梨子橙子蘋果的職責,違背了單一職責原則。並且,通過
//switch case的形式來判斷使用哪一種水果的計算方式,如果,此時我們需要再增加一種水果-西瓜的計算,
//那麼就需要在calculatePrice(int number, int type)函數增加判斷。
//不斷的增加或者修改會使這個類臃腫混亂難以維護
public class PriceCalculator {
    
    private static final int WATERMELON = 4;

    private static int watermelonPrice(int number) {
        return number * 10;
    }

    public static int calculatePrice(int number, int type) {
        switch (type) {
            case PEAR:
                return pearPrice(number);
            case ORANGE:
                return orangePrice(number);
            case APPLE:
                return applePrice(number);
            case WATERMELON:
                return watermelonPrice(number);
            default:
                return -1;
        }
    }
}


//-----------------------策略模式------------------------------

public interface CalculateStrategy {
    /**
     * 計算接口 按數量計算價格
     * @param number 數量
     * @return 總價
     */
    int calculatePrice(int number);
}

//梨子計算策略
public class PearStrategy implements CalculateStrategy{
    @Override
    public int calculatePrice(int number) {
        return number * 2;
    }
}

//橙子計算策略
public class OrangeStrategy implements CalculateStrategy {
    @Override
    public int calculatePrice(int number) {
        return number * 5;
    }
}

//蘋果計算策略
public class AppleStrategy implements CalculateStrategy{
    @Override
    public int calculatePrice(int number) {
        return number * 8000;
    }
}

//價格計算類
public class PriceCalculator {

    public static int calculatePrice(int number,CalculateStrategy strategy) {
        return strategy.calculatePrice(number);
    }
}

//使用:計算10個梨子的價格
PriceCalculator.calculatePrice(10,new PearStrategy());

//同樣,如果此時我們需要再增加一種水果-西瓜的計算,那麼只需新增西瓜的計算策略
public class WatermelonStrategy implements CalculateStrategy {
    @Override
    public int calculatePrice(int number) {
        return number * 10;
    }
}

7.狀態模式

狀態模式與策略模式結構幾乎是一樣的,但它們的目的、本質完全不一樣,狀態模式的行爲是平行的,不可替換的。策略模式的行爲是彼此獨立的,可相互替換的。

//訂單類 每一個訂單有多個按鈕 不同的訂單狀態對應不同的操作
public class OrderState {

    //未付款 -> 付款 取消 申請衆籌
    public final static int UNPAID = 1;
    //已付款 -> 退款 確認收貨
    public final static int PAID = 2;
    //已完成 -> 評價 刪除
    public final static int COMPLETED = 3;

    private int mState = UNPAID;


    public void setmState(int mState) {
        this.mState = mState;
    }

    /**
     * 按鈕A的操作
     */
    public void buttonA() {
        switch (mState) {
            case UNPAID:
                System.out.println("執行付款操作");
                break;
            case PAID:
                System.out.println("執行退款操作");
                break;
            case COMPLETED:
                System.out.println("執行評價操作");
                break;
        }
    }

    /**
     * 按鈕B的操作
     */
    public void buttonB() {
        if (mState == UNPAID) {
            System.out.println("執行取消操作");
        } else if (mState == PAID) {
            System.out.println("執行確認收貨操作");
        } else if (mState == COMPLETED) {
            System.out.println("執行刪除操作");
        }
    }

    /**
     * 按鈕C的操作
     */
    public void buttonC() {
        if (mState == UNPAID) {
            System.out.println("執行申請衆籌操作");
        } else if (mState == PAID) {
            System.out.println("按鈕無對應操作,恭喜發財");
        } else if (mState == COMPLETED) {
            System.out.println("按鈕隱藏,恭喜發財");
        }
    }
}

//按鈕點擊
public void buttonClick() {
    OrderState order = new OrderState();
    order.setmState(OrderState.UNPAID);
    order.buttonA();
    order.buttonB();
    order.buttonC();
}

//分析:通過mState標識訂單狀態,並且根據mState訂單按鈕會對應不同的操作,
//導致了每個功能中都需要使用switch-case/if-else,
//當有更多的訂單狀態及按鈕的時候,代碼將更爲複雜混亂

//--------------------------狀態模式---------------------------

//通多對態去除重複,雜亂的switch-case/if-else是狀態模式的精髓所在,但同時,也增加了系統類及對象。。。

//按鈕接口 定義按鈕操作函數 根據不同的訂單狀態函數操作也不一樣
public interface IButtonState {

    void buttonA();

    void buttonB();

    void buttonC();
}

//具體訂單狀態實現操作函數
public class UnpaidState implements IButtonState {
    @Override
    public void buttonA() {
        System.out.println("執行付款操作");
    }

    @Override
    public void buttonB() {
        System.out.println("執行付款操作");
    }

    @Override
    public void buttonC() {
        System.out.println("執行申請衆籌操作");
    }
}

public class PaidState implements IButtonState {
    @Override
    public void buttonA() {
        System.out.println("執行退款操作");
    }

    @Override
    public void buttonB() {
        System.out.println("執行確認收貨操作");
    }

    @Override
    public void buttonC() {
        System.out.println("按鈕無對應操作,恭喜發財");
    }
}

public class CompletedState implements IButtonState {
    @Override
    public void buttonA() {
        System.out.println("執行評價操作");
    }

    @Override
    public void buttonB() {
        System.out.println("執行刪除操作");
    }

    @Override
    public void buttonC() {
        System.out.println("按鈕隱藏,恭喜發財");
    }
}

//訂單狀態接口
public interface IOrderState {

    void unpaid();

    void paid();

    void completed();
}

//訂單類
public class OrderState implements IOrderState {

    private IButtonState mButtonState;

    public void setmButtonState(IButtonState mButtonState) {
        this.mButtonState = mButtonState;
    }

    public void buttonA() {
        mButtonState.buttonA();
    }

    public void buttonB() {
        mButtonState.buttonB();
    }

    public void buttonC() {
        mButtonState.buttonC();
    }

    @Override
    public void unpaid() {
        setmButtonState(new PaidState());
    }

    @Override
    public void paid() {
        setmButtonState(new PaidState());
    }

    @Override
    public void completed() {
        setmButtonState(new CompletedState());
    }
}

//按鈕點擊
public void buttonClick() {
    OrderState order = new OrderState();
    order.paid();
    order.buttonA();
    order.buttonB();
    order.buttonC();
}

打印日誌:
執行退款操作
執行確認收貨操作
按鈕無對應操作,恭喜發財

PS:狀態模式用在需要根據不同的登錄狀態對應不同操作的事件上挺不錯的

8.責任鏈模式

多個對象可以處理同一請求,將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它爲止。(與view的事件分發機制類似)

// 抽象請求者
public abstract class AbstractRequest {
    private Object object;

    public AbstractRequest(Object object) {
        this.object = object;
    }

    /**
     * 獲取處理對象內容
     * @return
     */
    public Object getContent() {
        return object;
    }

    /**
     * 獲取處理對象請求級別
     * @return
     */
    public abstract int getRequestLevel();
}

//抽象處理者
public abstract class AbstractHandler {
    //下一節點上的處理者對象
    protected AbstractHandler nextHandler;

    public final void handleRequest(AbstractRequest request) {
        //判斷當前處理者對象的處理級別是否與處理者的處理級別一致
        if (getHandleLevel() == request.getRequestLevel()) {
            handle(request);
        } else {
            if (nextHandler != null) {
                nextHandler.handleRequest(request);
            } else {
                System.out.println("所有處理者對象均不能處理該請求");
            }
        }
    }

    /**
     * 獲取處理者對象的處理級別
     *
     * @return 處理級別
     */
    protected abstract int getHandleLevel();

    /**
     * 每個處理者對象的具體處理方式
     *
     * @param request
     */
    protected abstract void handle(AbstractRequest request);
}

//具體請求者
public class Request1 extends AbstractRequest{

    public Request1(Object object) {
        super(object);
    }

    @Override
    public int getRequestLevel() {
        return 1;
    }
}

public class Request2 extends AbstractRequest{

    public Request2(Object object) {
        super(object);
    }

    @Override
    public int getRequestLevel() {
        return 2;
    }
}

public class Request3 extends AbstractRequest {

    public Request3(Object object) {
        super(object);
    }

    @Override
    public int getRequestLevel() {
        return 3;
    }
}

//具體處理者
public class Handler1 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 1;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler1:" + request.getRequestLevel() + " 內容:" + request.getContent());
    }
}

public class Handler2 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 2;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler2:" + request.getRequestLevel() + " 內容:" + request.getContent());
    }
}

public class Handler3 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 3;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handler3:" + request.getRequestLevel() + " 內容:" + request.getContent());
    }
}

//請求者發起請求
public void request() {
    
    //處理者對象
    AbstractHandler handler1 = new Handler1();
    AbstractHandler handler2 = new Handler2();
    AbstractHandler handler3 = new Handler3();

    //設置當前處理者的下一個節點的處理者對象
    handler1.nextHandler = handler2;
    handler2.nextHandler = handler3;

    //請求者
    AbstractRequest request1 = new Request1("Request1");
    AbstractRequest request2 = new Request2("Request2");
    AbstractRequest request3 = new Request3("Request3");

    //總是從鏈式的首端handler1發起請求
    handler1.handleRequest(request1);
    handler1.handleRequest(request2);
    handler1.handleRequest(request3);
}

//日誌打印
Handler1:1 內容:Request1
Handler2:2 內容:Request2
Handler3:3 內容:Request3

9.解釋器模式 (略)

10.命令模式

更弱的耦合性,更靈活的控制性,更好的擴展性,但同時也大量衍生類產生。

業務: 男朋友命令女朋友 (在正常情況下想都不要想)

//接收者角色 (你的女朋友)
//命令模式中唯一處理代碼邏輯的地方
public class GirlFriend {

    public void cooking() {
        System.out.println("做飯");
    }

    public void sweeping() {
        System.out.println("清掃");
    }

    public void sleeping() {
        System.out.println("暖牀");
    }
}

//通常情況下會這樣寫:
public void command() {
        
    GirlFriend girlFriend = new GirlFriend();
    girlFriend.sleeping();
    girlFriend.sweeping();
    girlFriend.cooking();
}

//------------------------命令模式-----------------------------

//命令者抽象 定義執行方法
public interface Command {

    /**
     * 命令執行方法
     */
    void execute();
}

//具體命令者命令  (發佈的命令,誰執行命令)
public class CookingCommand implements Command{

    private GirlFriend girlFriend;

    public CookingCommand(GirlFriend girlFriend) {
        this.girlFriend = girlFriend;
    }

    @Override
    public void execute() {
        girlFriend.cooking();
    }
}

public class SleepingCommand implements Command{

    private GirlFriend girlFriend;

    public SleepingCommand(GirlFriend girlFriend) {
        this.girlFriend = girlFriend;
    }

    @Override
    public void execute() {
        girlFriend.sleeping();
    }
}

public class SweepingCommand implements Command{

    private GirlFriend girlFriend;

    public SweepingCommand(GirlFriend girlFriend) {
        this.girlFriend = girlFriend;
    }

    @Override
    public void execute() {
        girlFriend.sweeping();
    }
}

//請求者類 命令發起者
public class BoyFriend {
    private CookingCommand cookingCommand ;
    private SweepingCommand sweepingCommand;
    private SleepingCommand sleepingCommand;

    public void setCookingCommand(CookingCommand cookingCommand) {
        this.cookingCommand = cookingCommand;
    }

    public void setSweepingCommand(SweepingCommand sweepingCommand) {
        this.sweepingCommand = sweepingCommand;
    }

    public void setSleepingCommand(SleepingCommand sleepingCommand) {
        this.sleepingCommand = sleepingCommand;
    }

    public void letSheGoToCooking() {
        //命令執行
        cookingCommand.execute();
    }

    public void letSheGoToSweeping() {
        sweepingCommand.execute();
    }

    public void letSheGoToSleeping() {
        sleepingCommand.execute();
    }
}

//使用:他命令她
public void command() {

    //首先要有一個女朋友
    GirlFriend girlFriend = new GirlFriend();

    //根據女朋友的作用構建命令
    CookingCommand cookingCommand = new CookingCommand(girlFriend);
    SweepingCommand sweepingCommand = new SweepingCommand(girlFriend);
    SleepingCommand sleepingCommand = new SleepingCommand(girlFriend);

    //確認男朋友可以讓女朋友執行哪些不同的命令
    BoyFriend boyFriend = new BoyFriend();
    boyFriend.setCookingCommand(cookingCommand);
    boyFriend.setSweepingCommand(sweepingCommand);
    boyFriend.setSleepingCommand(sleepingCommand);

    //接下來具體要讓女朋友幹啥男朋友說了算
    boyFriend.letSheGoToSleeping();
    boyFriend.letSheGoToSweeping();
    boyFriend.letSheGoToCooking();
}

//使用日誌打印:
暖牀
清掃
做飯

PS :Android 幾種創建型設計模式通道

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章