亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

對比Java設計模式編程中的狀態(tài)模式和策略模式

 更新時間:2016年04月27日 11:54:45   作者:花名有孚  
這篇文章主要介紹了Java設計模式編程中的狀態(tài)模式和策略模式對比,文中列舉了兩種模式的相似點和不同點,并都舉了代碼的實例作為參照,需要的朋友可以參考下

為了能在Java應用程序中正確的使用狀態(tài)模式和策略模式,開發(fā)人員需要清楚地知道這兩種模式之間的區(qū)別。盡管狀態(tài)模式和策略模式的結構非常相似,它們又同樣遵循開閉原則,都代表著SOLID設計原則的'O',但它們的意圖是完全不同的。Java中的策略模式是對一組相關的算法進行封裝,給調用方提供了運行時的靈活性。調用方可以在運行時選擇不同的算法,而不用修改使用策略的那個Context類。使用策略模式的經(jīng)典例子包括實現(xiàn)加密算法,壓縮算法,以及排序算法。另一方面,狀態(tài)模式使用一個對象可以在不同的狀態(tài)下表現(xiàn)出不同的行為。真實世界里的對象也是有狀態(tài)的,并且它們會隨著狀態(tài)的不同而有不同的表現(xiàn),比方說自動售貨機,它只會在hasCoin狀態(tài)下才能出售物品,如果你不塞硬幣進去它是不會售貨的?,F(xiàn)在你可以很清楚地看到策略模式和狀態(tài)模式的區(qū)別了,它們的目的是不一樣的。狀態(tài)模式可以幫助對象來管理它的狀態(tài),而策略模式使得客戶端可以選擇不同的行為。還有一個不太容易看到的區(qū)別是,誰去驅動行為的改變。在策略模式中,是客戶端驅動的,它給上下文信息提供了不同的策略,而在狀態(tài)模式中,狀態(tài)的遷移是由Context或者State對象自己來管理的。同樣的,如果你在State對象里面進行狀態(tài)的修改,它必須持有Context的引用,也就是說對自動售貨機而言,它可以調用setState方法來修改當前Context的狀態(tài)。另一方面,策略對象不會持有Context的引用 ,它的客戶端將選中的策略傳遞給Context。策略模式和狀態(tài)模式是最容易碰見的關于Java設計模式的面試題,在這篇關于Java設計模式的文章里,我們將會對這點進行詳細的介紹。我們會探索這兩種模式的相同點與不同點,這有助于提高你對這兩種模式的理解。

狀態(tài)模式和策略模式的相似點:
如果你看下策略模式和狀態(tài)模式的UML圖,它們看起來非常相似。在狀態(tài)模式中,使用State對象來改變行為的的對象叫Context對象,類似的在策略模式中,使用Strategy對象來改變行為的對象也是Context對象。記住,客戶端是和Context對象交互的。在狀態(tài)模式中,Context代理了狀態(tài)對象的方法調用,Context中的當前對象就是具體的狀態(tài)對象,而在策略模式中,Context操作的也是策略對象,這個對象要么作為參數(shù)傳入進來,要么是在創(chuàng)建Context對象的時候就已經(jīng)提供了。

我們再來看一下這兩種核心的Java設計模式的一些相似點:

狀態(tài)模式和策略模式都很容易新增新的狀態(tài)或者策略,而不會影響到使用它們的Context對象
兩種模式都遵循開閉的設計原則,也就是說你的設計對擴展開放而對修改關閉。在這兩個模式里,Context對修改是封閉的,新增狀態(tài)或者策略,你不需要修改其它狀態(tài)的Context對象,或者只需要很小的改動
正如狀態(tài)模式中Context對象會有一個初始狀態(tài)一樣,策略模式中的Context通常也有一個默認的策略。
狀態(tài)模式以不同的狀態(tài)對象的方式來封裝不同的行為,而策略模式以不同的策略對象來封裝不同的行為。
這兩種模式都依賴具體的子類來實現(xiàn)具體的行為。每一個具體的策略都擴展自一個抽象的策略類,每個狀態(tài)也都是用來表示狀態(tài)的接口或者抽象類的子類。


狀態(tài)模式實例

public class WindowState { 
  private String stateValue; 
   
  public WindowState(String stateValue) { 
    this.stateValue = stateValue; 
  } 
   
  public String getStateValue() { 
    return stateValue; 
  } 
 
  public void setStateValue(String stateValue) { 
    this.stateValue = stateValue; 
  } 
   
  public void handle() { 
    /* 
     * 根據(jù)不同狀態(tài)做不同操作, 再切換狀態(tài) 
     */ 
    if ("窗口".equals(stateValue)) { 
      switchWindow(); 
      this.stateValue = "全屏"; 
    } else if ("全屏".equals(stateValue)) { 
      switchFullscreen(); 
      this.stateValue = "窗口"; 
    } 
  } 
   
  private void switchWindow() { 
    System.out.println("切換為窗口狀態(tài)"); 
  } 
   
  private void switchFullscreen() { 
    System.out.println("切換為全屏狀態(tài)"); 
  } 
   
} 
/** 
 * 狀態(tài)的使用 
 */ 
public class WindowContext { 
  private WindowState state; 
   
  public WindowContext(WindowState state) { 
    this.state = state; 
  } 
   
  public WindowState getState() { 
    return state; 
  } 
   
  public void setState(WindowState state) { 
    this.state = state; 
  } 
   
  public void switchState() { 
    this.state.handle(); 
  } 
} 

/* 
 * 狀態(tài)(State)模式 行為型模式 
 * 既改變對象的狀態(tài),又改變對象的行為 
 * 根據(jù)狀態(tài),改變行為 
 */ 
public class Test { 
  public static void main(String[] args) { 
    /* 
     * 本例的 狀態(tài)值只有兩個,由狀態(tài)類自身控制 
     * 也可以把狀態(tài)值的控制,交由客戶端來設置 
     */ 
    WindowContext context = new WindowContext(new WindowState("窗口")); 
    context.switchState(); 
    context.switchState(); 
    context.switchState(); 
    context.switchState(); 
 
  } 
} 

打印

切換為窗口狀態(tài) 
切換為全屏狀態(tài) 
切換為窗口狀態(tài) 
切換為全屏狀態(tài) 


策略模式實例

/** 
 * 商品促銷 
 * 本類為:收取現(xiàn)金的類 
 */ 
public interface ICashSuper { 
   double acceptCash(double money); 
} 
/** 
 * 正常收取現(xiàn)金 
 * @author stone 
 * 
 */ 
public class CashNormal implements ICashSuper { 
 
  @Override 
  public double acceptCash(double money) { 
    return money; 
  } 
 
} 

/** 
 * 打折收取現(xiàn)金 
 * @author stone 
 * 
 */ 
public class CashRebate implements ICashSuper { 
  private double rebate; //折扣 
  public CashRebate (double rebate) { 
    this.rebate = rebate; 
  } 
 
  @Override 
  public double acceptCash(double money) { 
    return new BigDecimal(money * rebate / 10).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); 
  } 
   
   
} 


/** 
 * 讓利返現(xiàn) 收取現(xiàn)金 
 * @author stone 
 * 
 */ 
public class CashReturn implements ICashSuper { 
  private double moneyCondition; //返現(xiàn)底限金額 
  private double returnMoney; //返還金額 
  public CashReturn(double moneyCondition, double returnMoney) { 
    this.moneyCondition = moneyCondition; 
    this.returnMoney = returnMoney; 
  } 
 
  @Override 
  public double acceptCash(double money) {//多重返利 
    if (money >= moneyCondition) { 
      return money - Math.floor(money / moneyCondition) * returnMoney; 
    } else { 
      return money; 
    } 
  } 
   
   
} 

/** 
 * 根據(jù)傳遞的的策略類,執(zhí)行相應的行為 
 */ 
public class CashContext { 
  private ICashSuper casher; 
   
  public CashContext() { 
     
  } 
   
  public CashContext(ICashSuper casher) { 
    this.casher = casher; 
  } 
   
  public void setCasher(ICashSuper casher) { 
    this.casher = casher; 
  } 
   
  //根據(jù)具體的策略對象,調用它的算法行為 
  public double acceptCash(double money) { 
    return this.casher.acceptCash(money); 
  } 
   
} 

public class Test { 
  public static void main(String[] args) { 
    double money = 998; //原價 
    CashContext cashContext = new CashContext(new CashNormal()); 
    System.out.println("原價:" + cashContext.acceptCash(money)); //通常 策略 
     
    cashContext.setCasher(new CashRebate(8.5)); 
    System.out.println("打85折:" + cashContext.acceptCash(money)); //折扣  策略  85折 
     
    cashContext.setCasher(new CashReturn(300, 50)); 
    System.out.println("滿300 返50:" + cashContext.acceptCash(money)); //返現(xiàn) 策略  滿300 返50 
     
  } 
} 

打印

原價:998.0 
打85折:848.3 
滿300 返50:848.0 

策略模式和狀態(tài)模式的區(qū)別
我們已經(jīng)了解到這兩個模式在結構上非常相似,但它們仍有不同的地方。下面來看下它們之間一些關鍵的不同點。

  • 策略模式封裝了一系列的相關的算法,使用客戶端可以在運行時通過組合和委托來使用不同的行為,而狀態(tài)模式使得對象可以在不同的狀態(tài)下展現(xiàn)出不同的行為。
  • 這兩個模式的另一個不同之處在于狀態(tài)模式封裝的是對象的狀態(tài),而策略模式封裝的是一個算法或者策略。由于狀態(tài)是和對象耦合在一起的,它無法重用,而通過策略或者算法獨立于它的上下文,使得它們可以重復使用。
  • 狀態(tài)模式中,狀態(tài)本身會包含Context的引用,從而實現(xiàn)狀態(tài)遷移 ,但策略模式則沒有Context的引用
  • 具體的策略可以作為一個參數(shù)傳遞給使用它們的對象,比如說Collections.sort()接受一個Comparator,這是一個策略。另狀態(tài)本身 是 Context對象的一部分,隨著時間的遷移,Context對象會從一個狀態(tài)遷移遷移到另一個狀態(tài)下。
  • 盡管兩種模式都遵循了開閉原則,策略模式還遵循了單一職責原則,因為每個策略都 封裝的是獨立 的算法,不同的策略獨立于其它策略。改變一個策略并不會影響到另一個策略的實現(xiàn)。
  • 從理論上說,策略模式和狀態(tài)模式還有一個不同,前者定義的是一個對象“如何”去做一件事情,比如說如何對數(shù)據(jù)進行排序,而另一方面,狀態(tài)模式定義的是“什么”以及“何時“,比如說一個對象能做什么,某個時間點它處于哪個狀態(tài)。
  • 狀態(tài)的遷移順序在狀態(tài)模式中是定義好的,而策略模式則沒有這樣的要求??蛻舳丝梢噪S便選擇使用哪個策略。
  • 常見的策略模式的例子都是封裝算法,比如說排序算法,加密算法,或者壓縮算法。如果你發(fā)現(xiàn)代碼中需要使用到不同的算法,那么你可以考慮使用策略模式。而如果你需要管理狀態(tài)進行狀態(tài)間的遷移,而不希望嵌套許多條件語句,那么狀態(tài)模式就是你的首選,因為它非常簡單.
  • 最后也是最重要的一個區(qū)別在于,策略模式是由客戶端進行處理的,而狀態(tài)的改變Context或者State對象都可以進行。

這就是關于Java中策略模式和狀態(tài)模式的所有區(qū)別。正如我所說的,它們在UML圖中看起來非常類似,兩者都遵循了開閉原則,并且封裝了行為。策略模式是用來封裝算法或者策略的,它會在運行時作為參數(shù)或者組合對象來提供給Context對象,而狀態(tài)模式則是用來管理狀態(tài)遷移 的。

相關文章

  • JAVA面試題String產(chǎn)生了幾個對象

    JAVA面試題String產(chǎn)生了幾個對象

    這篇文章主要介紹了JAVA面試題 String s = new String("xyz");產(chǎn)生了幾個對象?,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • Spring Cloud CLI簡單介紹

    Spring Cloud CLI簡單介紹

    本文我們將介紹Spring Boot Cloud CLI(或簡稱Cloud CLI)。該工具為Spring Boot CLI提供了一組命令行增強功能,有助于進一步抽象和簡化Spring Cloud部署。感興趣的小伙伴們可以參考一下
    2018-12-12
  • 詳解CopyOnWriteArrayList是如何保證線程安全

    詳解CopyOnWriteArrayList是如何保證線程安全

    這篇文章主要為大家介紹了CopyOnWriteArrayList是如何保證線程安全講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Maven方式構建SpringBoot項目的實現(xiàn)步驟(圖文)

    Maven方式構建SpringBoot項目的實現(xiàn)步驟(圖文)

    Maven是一個強大的項目管理工具,可以幫助您輕松地構建和管理Spring Boot應用程序,本文主要介紹了Maven方式構建SpringBoot項目的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • 利用Socket.io 實現(xiàn)消息實時推送功能

    利用Socket.io 實現(xiàn)消息實時推送功能

    這篇文章主要介紹了利用Socket.io 實現(xiàn)消息實時推送功能,需要的朋友可以參考下
    2017-12-12
  • Springboot+Poi導入Excel表格實現(xiàn)過程詳解

    Springboot+Poi導入Excel表格實現(xiàn)過程詳解

    這篇文章主要介紹了Springboot+Poi導入Excel表格實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java操作pdf的工具類itext的處理方法

    Java操作pdf的工具類itext的處理方法

    這篇文章主要介紹了Java操作pdf的工具類itext,iText是一種生成PDF報表的Java組件,通過在服務器端使用Jsp或JavaBean生成PDF報表,客戶端采用超鏈接顯示或下載得到生成的報表,需要的朋友可以參考下
    2022-04-04
  • springBoot+mybaties后端多層架構的實現(xiàn)示例

    springBoot+mybaties后端多層架構的實現(xiàn)示例

    本文主要介紹了springBoot+mybaties后端多層架構的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 關于java數(shù)組與字符串相互轉換的問題

    關于java數(shù)組與字符串相互轉換的問題

    這篇文章主要介紹了java數(shù)組與字符串相互轉換的問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • Java的RocketMq隊列之消息可靠性詳解

    Java的RocketMq隊列之消息可靠性詳解

    這篇文章主要介紹了Java的RocketMq隊列之消息可靠性詳解,生產(chǎn)者通過網(wǎng)絡發(fā)送消息給 Broker,當 Broker 收到之后,將會返回確認響應信息給 Producer,所以生產(chǎn)者只要接收到返回的確認響應,就代表消息在生產(chǎn)階段未丟失,需要的朋友可以參考下
    2024-01-01

最新評論