程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Java與設計模式-策略模式

Java與設計模式-策略模式

編輯:JAVA綜合教程

Java與設計模式-策略模式


在實際開發中,可能會遇到這樣一個情況,某一功能的實現分為多種算法,這些算法可以認定為策略,在實際操作時選擇不同算法或策略進行操作得出最終結果。在實際生活中,這些例子也是舉不勝舉,例如,商場舉行活動,滿100元減10元,滿200元減30元,滿500元減100元等等...這樣每消費一筆,根據這一筆錢消費的多少,計算最終應支付的錢對應著不同的算法,這些對應的不同計算方法就可以認定為是不同的策略。在某東購物時,根據不同的用戶等級,打折力度也是不同的。

策略模式的UML類圖參照下圖:

\

假如沒有策略模式,實現某東購物計算最終付款的方法怎樣呢?

package com.strategy.demo;

public class NoStrategy {
	/**
	 * 不使用測量模式實現
	 * @param args
	 */
	private static final int NOCARDUSER=1;
	private static final int IRONCARDUSER=2;
	private static final int GOLDCARDUSER=3;
	

	public static void main(String[] args) {
		NoStrategy NoStrategy1=new NoStrategy();
		NoStrategy NoStrategy2=new NoStrategy();
		NoStrategy NoStrategy3=new NoStrategy();
		
		System.out.println("沒有卡牌的買家買100元貨物最終應付款:"+NoStrategy1.getPrice(100.0, 1));
		
		System.out.println("鐵牌的買家買100元貨物最終應付款:"+NoStrategy2.getPrice(100.0, 2));
		
		System.out.println("金牌的買家買100元貨物最終應付款:"+NoStrategy3.getPrice(100.0, 3));

	}
	
	
	private double getNoCardPrice(double price){
		 return price;
	}
	
	private double getIronCardPrice(double price){
		 return price*0.9;
	}
	
	private double getGoldCardPrice(double price){
		 return price*0.7;
	}
	
	
	private double getPrice(double price,int type){
		 if(type==NOCARDUSER){
			 return getNoCardPrice(price);
		 }else if(type ==IRONCARDUSER){
			 return getIronCardPrice(price);
		 }else if(type ==GOLDCARDUSER){
			 return getGoldCardPrice(price);
		 }else {
			 return 0;
		 }
	}

}

運行實例:

\

呀,得出正確的答案了,這時你是不是應該滿足了呢,應該高枕無憂了呢?突然,主管說要增加鑽石用戶的類別,鑽石用戶打六折,這時你怎麼實現呢?在裡面在增加鑽石用戶的類型,再增加計算鑽石用戶的方法,再再最後的判斷裡增加i f else? 這樣的確可以實現功能,但是是不是不滿足開閉原則呢?而且隨著用戶種類的不斷增加,你的if else是不是也越來越長,邏輯也越來越復雜呢?導致系統擴展性和穩定性越來越差呢? 所以,這種方式在實際中顯然實不可取的,下面我們看一下如何使用策略模式來實現上面的需求。

1.PriceStrategyInterface 接口,對應UML類圖中的Strategy接口:

package com.strategy.demo;

public interface PriceStrategyInterface {

	double calPrice(double price);
}


2.實現類,無卡用戶:

package com.strategy.demo;

public class NoCardUserStrategy implements PriceStrategyInterface {
	/**
	 * 無牌買家,原價
	 */

	@Override
	public double calPrice(double price) {
		return price;
	}

}


3.實現類,鐵卡用戶:

package com.strategy.demo;

public class IronCardUserStrategy implements PriceStrategyInterface {
	/*
	 * 鐵牌買家
	 * (non-Javadoc)
	 * @see com.strategy.demo.PriceStrategyInterface#calPrice(double)
	 */

	@Override
	public double calPrice(double price) {
		return price*0.9;
	}

}


4.實現類,金卡用戶:

package com.strategy.demo;

public class GoldCardUserStrategy implements PriceStrategyInterface {
	/**
	 * 金牌買家
	 */

	@Override
	public double calPrice(double price) {
		return price*0.7;
	}

}


5.環境對象,用來操作策略:

package com.strategy.demo;

public class PriceContext {
	/**
	 * 操作類
	 */

	PriceStrategyInterface priceStrategyInterface;
	/*
	 * 通過初始化傳入對象
	 */
	public PriceContext(PriceStrategyInterface priceStrategyInterface) {
		this.priceStrategyInterface=priceStrategyInterface;
	}
	/*
	 * 通過對象計算返回值
	 */
	public double getPrice(double price){
		 return priceStrategyInterface.calPrice(price);
	}
}

環境對象初始化時,將對應的策略對象傳入,然後調用方法返回計算值。

6.構建測試類,測試:

package com.strategy.demo;

public class TestClass {

	public static void main(String[] args) {
		PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
		System.out.println("沒有卡牌的買家買100元貨物最終應付款:"+priceContext.getPrice(100.0));
		
		PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
		System.out.println("鐵牌的買家買100元貨物最終應付款:"+priceContext2.getPrice(100.0));
		
		PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
		System.out.println("金牌的買家買100元貨物最終應付款:"+priceContext3.getPrice(100.0));

	}

}

運行上面的實例:

\

得到了和第一個方法一樣的正確答案,這時我們假如要增加一個鑽石買家的種類,怎麼實現呢?我們只需要增加一個策略實現類:

package com.strategy.demo;

public class DiamondUserStrategy implements PriceStrategyInterface {

	@Override
	public double calPrice(double price) {
		return price*0.6;
	}

}


然後測試類增加一條鑽石類買家的購物:

package com.strategy.demo;

public class TestClass {

	public static void main(String[] args) {
		PriceContext priceContext=new PriceContext(new NoCardUserStrategy());
		System.out.println("沒有卡牌的買家買100元貨物最終應付款:"+priceContext.getPrice(100.0));
		
		PriceContext priceContext2=new PriceContext(new IronCardUserStrategy());
		System.out.println("鐵牌的買家買100元貨物最終應付款:"+priceContext2.getPrice(100.0));
		
		PriceContext priceContext3=new PriceContext(new GoldCardUserStrategy());
		System.out.println("金牌的買家買100元貨物最終應付款:"+priceContext3.getPrice(100.0));
		
		PriceContext priceContext4=new PriceContext(new DiamondUserStrategy());
		System.out.println("鑽石卡的買家買100元貨物最終應付款:"+priceContext4.getPrice(100.0));

	}

}

運行實例:

\

是不是擴展起來特別容易?條理也十分清晰。總結一下策略模式的優點:

1. 結構清晰,使用簡單直觀;

2. 系統耦合性降低,擴展方便;

3. 操作封裝徹底,數據更為安全。(在TestClass中,只知道相關實現類,並不涉及具體計算方法)

當然,策略方式也存在一定的缺點:

\

由圖可以直觀的看出,隨著策略的不斷增加,子類數量變得龐大。

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