1. 程式人生 > >java 策略模式+簡單工廠模式+反射

java 策略模式+簡單工廠模式+反射

一、場景:在實際的專案開發中,我們常常會遇到這樣的問題,實現一個功能有多重方法或策略。

比如商場中計算價格的方法:

1、商場中沒有活動,那麼收費就是原價;

2、商場中有活動,打8折;

3、商場中有活動,滿300件100;

這三個中計算價格的方法就是三種策略。我們在不適用設計模式的情況下,就只能用if...else...獲取switch..case..來判斷使用哪一中計算方法,如下程式碼塊:

/**
* 增加打折功能,在客戶端增加一個折扣下拉選,打8折、7折、5折
 * @param price 單價
 * @param count 數量
 * @param discount 折扣
 * @return
 */
public Double calculation2(Double price,Double count,String discount){
Double result=0D;
if(price==null || count==null){
return result;
}
switch (discount) {
case "打8折":
result=price*count*0.8;
break;
case "打7折":
result=price*count*0.7;
break;
case "打5折":
result=price*count*0.5;
break;
default:
result=price*count;
break;
}
return result;
}

這樣寫可以實現搞活動的功能,但是這樣寫程式碼屬於硬編碼,如果商場中不搞活動了或者新增加了一種活動規則,我們就需要重寫程式碼,擴充套件性不好,因此考慮使用策略模式。

二、策略模式

2.1 定義

策略模式(Strategy)定義了演算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。

2.2 結構


2.3 商場搞活動程式碼實現

(1)、抽象演算法類,抽象出了計算價格的演算法。

abstract class CushSuper {
	public abstract double attachMoney(double money);
}

(2)、具體演算法1,正常收費

public class CushNormal extends CushSuper{
	@Override
	public double attachMoney(double money) {
		return money;
	}
}

(3)、具體演算法2,打折收費

public class CushRebate extends CushSuper{

	private double cushRebate=1d;
	public CushRebate(String moneyRebate) {
		this.cushRebate=Double.parseDouble(moneyRebate);
	}
	
	/*
	 * <p>折扣收費 </p>   
	 * @param money
	 * @return  
	 */
	@Override
	public double attachMoney(double money) {
		double result=money*cushRebate;
		return result;
	}

}

(4)、具體演算法3,滿減收費

public class CushReturn extends CushSuper{
	
	private double cushContidion=0d;
	private double cushReturn=0;
	public CushReturn(String cushContidion,String cushReturn) {
		this.cushContidion=Double.parseDouble(cushContidion);
		this.cushReturn=Double.parseDouble(cushReturn);
	}
	
	/*
	 * <p>滿減收費 </p>   
	 * @param money
	 * @return   
	 */
	@Override
	public double attachMoney(double money) {
		double result=money-Math.floor(money/cushContidion)*cushReturn;
		return result;
	}

}

(5)、context上下文,維護一個對Strategy物件的引用。

public class CushContxt {

	private CushSuper cushSuper;
	public CushContxt(CushSuper cushSuper) {
		this.cushSuper=cushSuper;
	}
	
	public double getResult(double money){
		return cushSuper.attachMoney(money);
	}
}

(6)、客戶端使用

public class Test {
	public static void main(String[] args) {
		double price=10d;
		double count=3d;
		
		//計算總價
		Double money=price*count;
		//獲取輸入框中的型別
//		String type="正常收費";
		String type="打8折";
//		String type="打5折";
//		String type="滿300減100";
		CushContxt content=null;
		switch (type) {
		case "正常收費":
			content=new CushContxt(new CushNormal());
			break;
		case "打8折":
			content=new CushContxt(new CushRebate("0.8"));
			break;
		case "打5折":
			content=new CushContxt(new CushRebate("0.5"));
			break;
		case "滿300減100":
			content=new CushContxt(new CushReturn("300","100"));
			break;
		}
		if(content!=null){
			System.out.println(content.getResult(money));
		}	
	}
}

至此,策略模式的解釋已經結束,可以看出以上程式碼的優缺點:

優點:1、演算法可以自由切換。 2、避免使用多重條件判斷。 3、擴充套件性好。

缺點:1、客戶端必須知道所有的策略類,並自己決定由那個策略類。   2、策略類會很多。

解決這個缺點方法:策略+簡單工廠

三、策略+簡單工廠

為了解決客戶端必須知道所有的策略類,並自己決定由那個策略類這個缺點,可以使用策略+工廠模式。

改進CushContext類如下:

public class CushContext {
	
	CushSuper cushSuper=null;
	public CushContext(String type) {
		switch (type) {
		case "正常收費":
			cushSuper=new CushNormal();
			break;
		case "打8折":
			cushSuper=new CushRebate("0.8");
			break;
		case "打5折":
			cushSuper=new CushRebate("0.5");
			break;
		case "滿300減100":
			cushSuper=new CushReturn("300","100");
			break;	
		}
	}
	
	public double getResult(double money){
		return cushSuper.attachMoney(money);
	}
}

客戶端改為:

public class Test {
	//使用策略模式+簡單工廠模式實現
	public static void main(String[] args) {
		double price=10d;
		double count=3d;
		
		//計算總價
		Double money=price*count;
		//獲取輸入框中的型別
		String type1="正常收費";
		String type2="打8折";
		String type3="打5折";
		String type4="滿300減100";
		CushContext content=new CushContext(type1);
		//正常收費
		System.out.println(content.getResult(money));
		//打8折
		CushContext content2=new CushContext(type2);
		System.out.println(content2.getResult(money));
		//打5折
		CushContext content3=new CushContext(type3);
		System.out.println(content3.getResult(money));
		//滿300減100
		CushContext content4=new CushContext(type4);
		System.out.println(content4.getResult(money));
		
	}
}

優點:解決了需要在客戶端判斷使用那個實現的缺點;

缺點:在cashContext中用到了swith,也就是說,如果我們需要增加一種演算法,比如"滿200減50",就必須更改cashContext中的switch程式碼。

解決方法:策略+簡單工廠+反射

四、策略+簡單工廠+反射

改進CushContext類如下:

public class CushContext {
	
	 private static final String[] CUSH_CLASS_NAME = {  
        "main.java.celue.celue5.CushNormal",  
        "main.java.celue.celue5.CushRebate",  
        "main.java.celue.celue5.CushReturn"
    }; 
	
	CushSuper cushSuper=null;
	public CushContext(String type,Class[] paramsType, Object[] parmas) {
		int type2=Integer.parseInt(type);
		try {
			Class<?> clazz=Class.forName(CUSH_CLASS_NAME[type2]);
			Constructor<?> constructor=clazz.getConstructor(paramsType);
			this.cushSuper=(CushSuper)constructor.newInstance(parmas);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	
	public double getResult(double money){
		return cushSuper.attachMoney(money);
	}
}

客戶端改進:

public class Test {
	public static void main(String[] args) {
		double price=100d;
		double count=3d;
		//計算總價
		Double money=price*count;
		
		//正常收費
		Class[] paramTypes = {}; 
		Object[] params = {}; 
		CushContext context=new CushContext("0",paramTypes,params);
		System.out.println(context.getResult(money));
		//打8折
		Class[] paramTypes2 = {String.class}; 
		Object[] params2 = {"0.8"}; 
		CushContext context2=new CushContext("1",paramTypes2,params2);
		System.out.println(context2.getResult(money));
		//打5折
		Class[] paramTypes3 = {String.class}; 
		Object[] params3 = {"0.5"}; 
		CushContext context3=new CushContext("1",paramTypes3,params3);
		System.out.println(context3.getResult(money));
		//滿300減100
		Class[] paramTypes4 = {String.class,String.class}; 
		Object[] params4 = {"300","100"}; 
		CushContext context4=new CushContext("2",paramTypes4,params4);
		System.out.println(context4.getResult(money));
	}
}
以上就是策略模式的應用,由於本人是自己學習總結的,如果有寫的不對的地方,歡迎各位大神批評指出。

相關推薦

java 策略模式+簡單工廠模式+反射

一、場景:在實際的專案開發中,我們常常會遇到這樣的問題,實現一個功能有多重方法或策略。比如商場中計算價格的方法:1、商場中沒有活動,那麼收費就是原價;2、商場中有活動,打8折;3、商場中有活動,滿300件100;這三個中計算價格的方法就是三種策略。我們在不適用設計模式的情況下

Java 關於策略模式+簡單工廠模式下的思考

導讀   最近在做公司一個訊息閘道器的服務,包括:簡訊、微信、郵件等,所有請求通過一個入口,方便介面的管理(記錄日誌、介面限流白名單啥的)。如何寫這個介面呢,還有為了以後擴充套件,對接過簡訊、微信、公眾號的童鞋大概都瞭解,首先定義一個模板,然後後臺傳入json,替換模板中的值,然後傳送。設計框架大概思路是這樣

JAVA 23種設計模式---工廠模式(簡單工廠模式)

寫在前面的話: java常用的設計模式有23種,設計模式就是為了重用程式碼、解耦、讓程式碼更容易讓他人理解、保證程式碼可靠性 設計模式遵循的原則有6個: 1、開閉原則(Open Close Principle)   對擴充套件開放,對修改關閉。 2、里氏代換原則(Liskov S

java高階之簡單工廠模式

    定義 提供一個建立物件例項的功能,而無須關心其具體實現。被建立例項的型別可以是介面、抽象類、也可以是具體的類。 結構和說明 例項 介面 兩個實現類 簡單工廠類(Factor

Java設計模式-簡單工廠模式/工廠模式/抽象工廠模式

目錄 簡單工廠模式 工廠模式 抽象工廠模式 上述程式碼 GitHub 地址:https://github.com/baicun/designPatterns 共同點:建立一個類,對同樣操作的方法介面進行封裝,類似工廠管理生產線等情形。 優點:方便管理,易於拓展。 應用

淺談Java設計模式——簡單工廠模式

一、定義         通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。 二、類圖 三、理解         Operation為抽象類,它定義了一個抽象方法getResult;OperationAdd和OperationSubtra

Java——設計模式(簡單工廠模式)

* A:簡單工廠模式概述 * 簡單工廠模式又叫靜態工廠方法模式,它定義了一個具體的工廠類負責建立一些類的例項 * B:優點 * 客戶端不需要再負責物件的建立,從而明確了各個類的職責 *

Java中常見的設計模式---簡單工廠模式工廠方法模式和單例模式

在講設計模式之前,我們首先來說一下面向物件思想的設計原則,在實際的開發中,我們要想更深入的瞭解面向物件思想,就必須熟悉前人總結過的面向物件的思想的設計原則:1.單一職責原則:“高內聚,低耦合”,也就是說,每個類應該只有一個職責,對外只能提供一種功能,而引起類變化的原因應該只有

java語言實現建立型模式簡單工廠模式

一、描述 簡單工廠模式又名靜態工廠方法模式,是所有工廠模式中最簡單的一個,它定義一個具體的工廠類來負責建立所有類的物件並初始化建立的物件,它主要由3部分組成:工廠類、抽象類、實現抽象類的具體類,然後通過客戶端呼叫工廠類建立相應的物件。 注意:簡單工廠模式不屬於GoF總結的2

JAVA設計模式工廠模式(簡單工廠模式+工廠方法模式)

 在面向物件程式設計中, 最通常的方法是一個new操作符產生一個物件例項,new操作符就是用來構造物件例項的。但是在一些情況下, new操作符直接生成物件會帶來一些問題。舉例來說, 許多型別物件的創造需要一系列的步驟: 你可能需要計算或取得物件的初始設定; 選擇生成哪個子物件

《大話設計模式java實現之簡單工廠模式

《大話模式》這本書寫得不錯,可惜不是java版,現在有空,想著用java實現一下,寫到哪算哪 UML圖 程式碼結構圖 public class Client { public static void main(String[] args)

Java[Android]設計模式工廠模式(簡單工廠模式+工廠方法模式+抽象工廠模式)

1. 寫在前面  網上關於設計模式的文章已經非常詳盡了,寫這篇文章旨在給自己的學習做一個筆記和總結方便以後翻閱查詢,若對你有用可細學之若覺得膚淺可略之。  工廠模式屬於建立型設計模式,分為簡單工廠模式,工廠方法模式,抽象工廠模式三種,話不多說,請看下面一一道來。2. 簡單工廠

JAVA設計模式工廠模式(簡單工廠模式+工廠方法模式+抽象工廠模式)

http://blog.csdn.net/jason0539/article/details/23020989 http://blog.csdn.net/jason0539/article/details/44976775

設計模式Java語言)- 簡單工廠模式

  簡單工廠模式有稱為靜態工廠模式,屬於設計模式中的建立型模式。簡單工廠模式通過對外提供一個靜態方法來統一為類建立例項。簡單工廠模式的目的是實現類與類之間解耦,其次是客戶端不需要知道這個物件是如何被穿創建出來的,只需要呼叫簡單工廠模式的方法來統一建立就可以了,從而明確了各個類的職責。   一、建立簡單工廠模式

java設計模式-簡單工廠模式

簡單工廠模式詳解 1,概述   簡單工廠模式屬於建立型模式又叫做靜態工廠方法模式,它屬於類建立型模式。在簡單工廠模式中,可以根據引數的不同返回不同類的例項。   簡單工廠模式專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。   簡單工廠只需要傳入一個正確的引數,就可以獲取所需要的物件,

PHP面向對象-設計模式 單例模式 簡單工廠模式 工廠方法模式

單例 nbsp 私有化 {} 意義 pan php代碼 get fun 1.單例模式   單例模式是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個實例。即一個類只有一個對象實例。   要實現每一個類只有一個實例

設計模式--簡單工廠模式

-- nfa sum 處理 create new 功能 子類 工廠模式 近期又在看程傑的《大話設計模式》這本書,這真的是我超級喜歡的一本書。裏面的內容非常精彩。學習之余。將書中的內容整理出來,另外加上了一些自己的理解,方便日後自己回想並同一時候希望本筆記能夠對各位編程

C#設計模式——簡單工廠模式

turn static 現在 rri 介紹 return 天都 土豆 增加 一、引言   這個系列也是自己對設計模式的一些學習筆記,希望對一些初學設計模式的人有所幫助的,在上一個專題中介紹了單例模式,在這個專題中繼續為大家介紹一個比較容易理解的模式——簡單工廠模式。 二、簡

設計模式-簡單工廠模式

sha include highlight namespace 簡單工廠模式 case int 工廠模式 argv 簡單工廠模式:是一種實例化對象的方式,只要輸入實例化對象的名字,就可以通過工廠對象的相應工廠函數來制造你需要的對象 核心是,對於一個父類的多個繼承子類,工廠對

設計模式——簡單工廠模式

idt index init == set ces edev ini property 聲明:以下內容來源於《大話設計模式》,學習 簡單工廠模式類圖: 界面: 代碼: using System; using System.Collections.Generic; us