今天介紹一下策略模式,
稍微結合一下昨天介紹的簡單的工廠模式,
實現一些簡單的小工具,
這兩天有發現有一些基礎沒介紹到,
會找機會把基礎的思想補完一下。
定義一系列的演算法
,並且把這些算法,用介面封裝到有公共介面的策略類中
,使他們可以互相替換。
策略模式用
策略的介面
來替換在某個實體
ˋ中的方法
,
可以經由替換不同的策略
使得物件擁有不同的行為
。
經過策略的組合,我們得以獲得行為不同的物件。
優點:
缺點:
或許可以將這些行為不同的物件用工廠模式封裝起來,解決使用這些模式時需要先事先知道有哪些策略,並且需要自行決定使用哪些策略的問題。
假設我們要實現一個計算機的話...
先定義一個介面,用這個介面定義一系列演算法。
public interface IStrategy {
public int caculate(int a , int b);
}
將加減乘除等一系列的算法實現出來
public class add implements IStrategy {
@Override
public int caculate(int a, int b) {
return a + b;
}
}
public class minus implements IStrategy {
@Override
public int caculate(int a, int b) {
return a - b ;
}
}
public class multyply implements IStrategy {
@Override
public int caculate(int a, int b) {
return a * b;
}
}
public class divide implements IStrategy {
@Override
public int caculate(int a, int b) {
return a / b ;
}
}
用一個類裝這個算法,並且用昨天講到簡單的工廠模式封裝一下
public class Calculator {
private int now = 0 ;
private IStrategy strategy ;
// 策略模式
public int execute(int a , int b){
return strategy.caculate(a,b);
}
public void reset(){
this.now = 0 ;
}
// 簡單工廠模式
public void setStrategy(DoType doType) {
switch (doType){
case ADD:
this.strategy = new add();
break;
case MINUS:
this.strategy = new minus();
break;
case DIVIDE:
this.strategy = new divide();
break;
case MULTYPLY:
this.strategy = new multyply();
break;
}
}
enum DoType{
ADD , MINUS , DIVIDE , MULTYPLY
}
}
實現了一個簡單的計算機,
當然只有加減乘除的計算機的演算法不太複雜,
但是現在如果要加入一個次方的演算法,
我們也能很簡單的實現它。
因為還有一些時間我們試著再實現一種
假設我們現在需要一個根據里程數幫忙計價的計算機
public interface IStrategy {
public int calculate();
}
Bus & MRT 的里程計價方式
public class BusStrategy implements IStrategy {
@Override
public int calculate(int km) {
// 一段票15元
// 十公里內一段票,超過十公里兩段票
int count = 0 ;
if( km <= 10 ){
count = 1 ;
}else if( km > 10){
count = 2 ;
}
return count * 15 ;
}
}
public class MRTStrategy implements IStrategy {
@Override
public int calculate(int km) {
// 小於十公里20元,超過每五公里多五元
int result = 0 ;
if(km <= 0) return result ;
if(km <= 10) {
result = 20 ;
}
if(km > 10){
int count = (int)Math.ceil((((double)km - 10) / 5));
result = 20 + 5 * count ;
}
return result;
}
}
依據里程數計價的計算機,
只要選定你的移動方式(在這裡是MRT or Bus),
就可以根據移動方式來計算出需要的費用。
public class PriceCalculator {
IStrategy strategy;
private PriceCalculator(){};
public PriceCalculator(IStrategy strategy){
this.strategy = strategy;
}
public void setStrategy(IStrategy strategy) {
this.strategy = strategy;
}
public int calculate(int km){
return this.calculate(km,strategy);
}
public int calculate(int km , IStrategy strategy){
this.strategy = strategy;
return strategy.calculate(km);
}
}
今天的文章就先到這邊啦~
範例有兩個,但是都很簡單的!
大家有心也一定能夠掌握,
我們雖然不比別人聰明,甚至起步比別人慢,
但是只要有根性氣勢,
相信這種恆毅力才是真正的寶藏,
明天再繼續加油~
如果有什麼問題或錯誤的地方,歡迎留言或來信喔~
(手殘亂按剛打好的被刪掉了...簡單描述
先感謝邦友的文章!
MRTStrategy 有兩處錯誤
public class MRTStrategy implements IStrategy {
@Override
public int calculate(int km) {
// 小於十公里20元,超過每五公里五元
int result = 0 ;
if(km <= 0) return result ;
if(km <= 20) {
result = 20 ;
}
if(km > 20){
int count = (( km - 20 ) / 5 ) + 1 ;
result = result + 5 * count ;
}
return result;
}
}
已改正,感謝糾錯!!
小於十公里20元,超過每五公里多五元
依照這句話,15公里應該是25(=20+5)元,但是依照程式碼卻是30(= 20+5 * (((15-10)/5)+ 1))元,請問是我哪裡誤會了嗎?
看來我當時都在亂寫 XDDD
int count = (( km - 20 ) / 5 ) + 1 ;
我的猜測是這邊的 +1 想要達成的是未滿五公里以五公里計算,如果是這樣的話,我的建議如下
int count = (int)Math.ceil((((double)km - 10) / 5));
好呀,就採用你的 看起來沒有什麼錯誤