程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 比較Java設計形式編程中的狀況形式和戰略形式

比較Java設計形式編程中的狀況形式和戰略形式

編輯:關於JAVA

比較Java設計形式編程中的狀況形式和戰略形式。本站提示廣大學習愛好者:(比較Java設計形式編程中的狀況形式和戰略形式)文章只能為提供參考,不一定能成為您想要的結果。以下是比較Java設計形式編程中的狀況形式和戰略形式正文


為了能在Java運用法式中准確的應用狀況形式和戰略形式,開辟人員須要清晰地曉得這兩種形式之間的差別。雖然狀況形式和戰略形式的構造異常類似,它們又異樣遵守開閉准繩,都代表著SOLID設計准繩的'O',但它們的意圖是完整分歧的。Java中的戰略形式是對一組相干的算法停止封裝,給挪用方供給了運轉時的靈巧性。挪用方可以在運轉時選擇分歧的算法,而不消修正應用戰略的誰人Context類。應用戰略形式的經典例子包含完成加密算法,緊縮算法,和排序算法。另外一方面,狀況形式應用一個對象可以在分歧的狀況下表示出分歧的行動。真實世界裡的對象也是有狀況的,而且它們會跟著狀況的分歧而有分歧的表示,比喻說主動售貨機,它只會在hasCoin狀況下能力出售物品,假如你不塞硬幣出來它是不會售貨的。如今你可以很清晰地看到戰略形式和狀況形式的差別了,它們的目標是紛歧樣的。狀況形式可以贊助對象來治理它的狀況,而戰略形式使得客戶端可以選擇分歧的行動。還有一個不太輕易看到的差別是,誰去驅動行動的轉變。在戰略形式中,是客戶端驅動的,它給高低文信息供給了分歧的戰略,而在狀況形式中,狀況的遷徙是由Context或許State對象本身來治理的。異樣的,假如你在State對象外面停止狀況的修正,它必需持有Context的援用,也就是說對主動售貨機而言,它可以挪用setState辦法來修正以後Context的狀況。另外一方面,戰略對象不會持有Context的援用 ,它的客戶端將選中的戰略傳遞給Context。戰略形式和狀況形式是最輕易碰見的關於Java設計形式的面試題,在這篇關於Java設計形式的文章裡,我們將會對這點停止具體的引見。我們會摸索這兩種形式的雷同點與分歧點,這有助於進步你對這兩種形式的懂得。

狀況形式和戰略形式的類似點:
假如你看下戰略形式和狀況形式的UML圖,它們看起來異常類似。在狀況形式中,應用State對象來轉變行動的的對象叫Context對象,相似的在戰略形式中,應用Strategy對象來轉變行動的對象也是Context對象。記住,客戶端是和Context對象交互的。在狀況形式中,Context署理了狀況對象的辦法挪用,Context中確當前對象就是詳細的狀況對象,而在戰略形式中,Context操作的也是戰略對象,這個對象要末作為參數傳入出去,要末是在創立Context對象的時刻就曾經供給了。

我們再來看一下這兩種焦點的Java設計形式的一些類似點:

狀況形式和戰略形式都很輕易新增新的狀況或許戰略,而不會影響到應用它們的Context對象
兩種形式都遵守開閉的設計准繩,也就是說你的設計對擴大開放而對修正封閉。在這兩個形式裡,Context對修正是關閉的,新增狀況或許戰略,你不須要修正其它狀況的Context對象,或許只須要很小的修改
正如狀況形式中Context對象會有一個初始狀況一樣,戰略形式中的Context平日也有一個默許的戰略。
狀況形式以分歧的狀況對象的方法來封裝分歧的行動,而戰略形式以分歧的戰略對象來封裝分歧的行動。
這兩種形式都依附詳細的子類來完成詳細的行動。每個詳細的戰略都擴大自一個籠統的戰略類,每一個狀況也都是用來表現狀況的接口或許籠統類的子類。


狀況形式實例

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() { 
    /* 
     * 依據分歧狀況做分歧操作, 再切換狀況 
     */ 
    if ("窗口".equals(stateValue)) { 
      switchWindow(); 
      this.stateValue = "全屏"; 
    } else if ("全屏".equals(stateValue)) { 
      switchFullscreen(); 
      this.stateValue = "窗口"; 
    } 
  } 
   
  private void switchWindow() { 
    System.out.println("切換為窗口狀況"); 
  } 
   
  private void switchFullscreen() { 
    System.out.println("切換為全屏狀況"); 
  } 
   
} 
/** 
 * 狀況的應用 
 */ 
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(); 
  } 
} 

/* 
 * 狀況(State)形式 行動型形式 
 * 既轉變對象的狀況,又轉變對象的行動 
 * 依據狀況,轉變行動 
 */ 
public class Test { 
  public static void main(String[] args) { 
    /* 
     * 本例的 狀況值只要兩個,由狀況類本身掌握 
     * 也能夠把狀況值的掌握,交由客戶端來設置 
     */ 
    WindowContext context = new WindowContext(new WindowState("窗口")); 
    context.switchState(); 
    context.switchState(); 
    context.switchState(); 
    context.switchState(); 
 
  } 
} 

打印

切換為窗口狀況 
切換為全屏狀況 
切換為窗口狀況 
切換為全屏狀況 


戰略形式實例

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

/** 
 * 打折收取現金 
 * @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(); 
  } 
   
   
} 


/** 
 * 讓利返現 收取現金 
 * @author stone 
 * 
 */ 
public class CashReturn implements ICashSuper { 
  private double moneyCondition; //返現底限金額 
  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; 
    } 
  } 
   
   
} 

/** 
 * 依據傳遞的的戰略類,履行響應的行動 
 */ 
public class CashContext { 
  private ICashSuper casher; 
   
  public CashContext() { 
     
  } 
   
  public CashContext(ICashSuper casher) { 
    this.casher = casher; 
  } 
   
  public void setCasher(ICashSuper casher) { 
    this.casher = casher; 
  } 
   
  //依據詳細的戰略對象,挪用它的算法行動 
  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)); //返現 戰略  滿300 返50 
     
  } 
} 

打印

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

戰略形式和狀況形式的差別
我們曾經懂得到這兩個形式在構造上異常類似,但它們仍有分歧的處所。上面來看下它們之間一些症結的分歧點。

  • 戰略形式封裝了一系列的相干的算法,應用客戶端可以在運轉時經由過程組合和拜托來應用分歧的行動,而狀況形式使得對象可以在分歧的狀況下展示出分歧的行動。
  • 這兩個形式的另外一個分歧的地方在於狀況形式封裝的是對象的狀況,而戰略形式封裝的是一個算法或許戰略。因為狀況是和對象耦合在一路的,它沒法重用,而經由過程戰略或許算法自力於它的高低文,使得它們可以反復應用。
  • 狀況形式中,狀況自己會包括Context的援用,從而完成狀況遷徙 ,但戰略形式則沒有Context的援用
  • 詳細的戰略可以作為一個參數傳遞給應用它們的對象,好比說Collections.sort()接收一個Comparator,這是一個戰略。另狀況自己 是 Context對象的一部門,跟著時光的遷徙,Context對象會從一個狀況遷徙遷徙到另外一個狀況下。
  • 雖然兩種形式都遵守了開閉准繩,戰略形式還遵守了單一職責准繩,由於每一個戰略都 封裝的是自力 的算法,分歧的戰略自力於其它戰略。轉變一個戰略其實不會影響到另外一個戰略的完成。
  • 從實際上說,戰略形式和狀況形式還有一個分歧,前者界說的是一個對象“若何”去做一件工作,好比說若何對數據停止排序,而另外一方面,狀況形式界說的是“甚麼”和“什麼時候“,好比說一個對象能做甚麼,某個時光點它處於哪一個狀況。
  • 狀況的遷徙次序在狀況形式中是界說好的,而戰略形式則沒有如許的請求。客戶端可以隨意選擇應用哪一個戰略。
  • 罕見的戰略形式的例子都是封裝算法,好比說排序算法,加密算法,或許緊縮算法。假如你發明代碼中須要應用到分歧的算法,那末你可以斟酌應用戰略形式。而假如你須要治理狀況停止狀況間的遷徙,而不願望嵌套很多前提語句,那末狀況形式就是你的首選,由於它異常簡略.
  • 最初也是最主要的一個差別在於,戰略形式是由客戶端停止處置的,而狀況的轉變Context或許State對象都可以停止。

這就是關於Java中戰略形式和狀況形式的一切差別。正如我所說的,它們在UML圖中看起來異常相似,二者都遵守了開閉准繩,而且封裝了行動。戰略形式是用來封裝算法或許戰略的,它會在運轉時作為參數或許組合對象來供給給Context對象,而狀況形式則是用來治理狀況遷徙 的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved