策略模式定義了算法族,分別封裝起來,讓它們之間能夠互相替換,此模式讓算法的變化獨立於使用算法的客戶。html
策略模式的精髓就在於將常常變化的一點提取出來,單獨變成一類,而且各個類別能夠相互替換和組合,類圖關係以下:java
結合策略模式的類圖,可知:git
策略模式經過context上下文類來自由的選擇所要採起的方法:github
public class AbstractContext {
AbstractStrategy strategy;
//初始化時傳入具體的策略對象
public AbstractContext(AbstractStrategy strategy) {
this.strategy = strategy;
}
//上下文接口,調用策略的具體方法
public void ContextInterface() {
strategy.ItsInterface();
}
}
複製代碼
而對應的方法都是繼承與同一個抽象的策略類:算法
public abstract class AbstractStrategy {
//留待子類本身實現
public void ItsInterface(){
}
}
複製代碼
具體的策略類實如今子類中進行重載,以下:設計模式
public class FakeStrategy extends AbstractStrategy{
@Override
//子類實現的具體方法
public void ItsInterface() {
System.out.println("I'm using this method");
}
}
PS:其餘各種方法同理
複製代碼
策略模式所要解決的問題主要是在多種算法極其類似的狀況下,讓對象根據上下文(context)進行具體實現的選擇。例如選擇出門的方式:騎車、開車、走路等等,甚至騎車一段時間、走路一段時間、坐飛機一段時間。markdown
我以爲《大話設計模式》舉的例子十分貼切:某商場搞促銷活動,有打折活動、滿減活動(兩個可同時進行),而且打折的力度和滿減的程度可能在從此須要進行修正,那麼應當如何設計整個系統呢?ide
假設如今商場有三種結算方式:正常結算、打折結算、返利結算。根據策略模式的思想,咱們能夠設計一個這樣的系統:oop
先建立一個抽象的上下文類,獲取傳入的具體優惠策略,調用getPrice()來獲取結果。post
public class CashContext {
private CashAbstract CashAbstract;
public CashContext(CashAbstract CashAbstract) {
this.CashAbstract = CashAbstract;
}
public double getResult(double money) {
return CashAbstract.acceptCash(money);
}
}
複製代碼
抽象策略類在這裏指的是所採用的收費方式:
public abstract class CashAbstract {
public abstract double acceptCash(double money);
}
複製代碼
商場活動一共有三種:正常收費(無活動)、打折收費、返利收費,這裏只給出返利收費的實現:
public class CashReturn extends CashAbstract {
//返利收費,初始化時必須輸入返利條件以及返利金額
private double moneyCondition = 0.0;
private double moneyReturn = 0.0d;
public CashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if (money >= moneyCondition) {
result = money - Math.floor(money / moneyCondition) * moneyReturn;
}
return result;
}
}
複製代碼
public class App {
public static void main(String[] args) {
CashContext cashContext = null;
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入活動內容:1是正常收費,2是返利收費,3是打折活動");
int in = scanner.nextInt();
String type = "";
switch (in) {
case 1:
cashContext = new CashContext(new CashNormal());
type += "正常收費";
break;
case 2:
cashContext = new CashContext(new CashReturn(300, 100));
type += "滿300返100";
break;
case 3:
cashContext = new CashContext(new CashRebate(0.8));
type += "打8折";
break;
default:
System.out.println("請輸入1/2/3");
break;
}
double totalPrices = 0;
System.out.print("請輸入單價:");
double price = scanner.nextDouble();
System.out.print("請輸入數量:");
double num = scanner.nextDouble();
totalPrices = cashContext.getPrice(price * num);
System.out.println("單價:" + price + ",數量:" + num + ",類型:" + type + ",合計:" + totalPrices);
scanner.close();
}
}
複製代碼
正常:
返利:
打折:
可見,咱們設計的收費系統是沒問題的。
策略模式的優勢就在於能夠靈活的選擇須要使用的算法,減小ifelse語句;
缺點就是,若是具體的策略類較多的話,各個策略類之間不具備複用性。
策略模式使用了哪些設計原則?
《大話設計模式》
《Head First 設計模式》
閒說設計模式:
大話設計模式(1)——單例模式 #掘金文章# juejin.cn/post/696772…