参考:

1、胡珊https://www.yuque.com/books/share/86438f6a-5e1d-4fea-8939-83c92a751d60/es9sog
2、《大话设计模式》

UML类图

image.png

合成:强关系
聚合:弱关系

简单工厂模式

image.png

  1. 把计算类用抽象函数给拆开;
  2. 把输入数据、判断运算符、计算,分别放入三个类中。其中判断运算符的类被称为工厂类,因为它要决定生产哪一种计算类。 ``` //计算类 public abstract class Operator { public abstract float operator(float numA, float numB); }

public class AddFunc extends Operator{

  1. @Override
  2. public float operator(float numA, float numB) {
  3. return numA + numB;
  4. }

}

public class MinusFun extends Operator{ @Override public float operator(float numA, float numB) { return numA - numB; } }

//判断运算符 public class ChooseOper {

  1. public static Operator chooseoper(String operateor) {
  2. Operator oper = null;
  3. switch (operateor) {
  4. case "+":
  5. oper = new AddFunc();
  6. break;
  7. case "-":
  8. oper = new MinusFun();
  9. break;
  10. default:
  11. }
  12. return oper;
  13. }

}

//控制台 public class Play { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println(“Please input number A”); float a = sc.nextFloat(); System.out.println(“Please input operator”); String oper = sc.next(); System.out.println(“Please input number B”); float b = sc.nextFloat();

  1. Operator operator = ChooseOper.chooseoper(oper);
  2. float result = operator.operator(a,b);
  3. System.out.println(result);
  4. }

}

  1. <a name="we5Rl"></a>
  2. # 策略模式
  3. 策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,<br />此模式让算法的变化,不会影响到使用算法的客户。
  4. <a name="d74aJ"></a>
  5. ## UML图
  6. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21416885/1643437846351-91b4190a-886d-4aec-a72f-03b29bb631e1.png#clientId=u1c4c5315-4693-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=378&id=ud5b34041&margin=%5Bobject%20Object%5D&name=image.png&originHeight=755&originWidth=1666&originalType=binary&ratio=1&rotation=0&showTitle=false&size=361238&status=done&style=none&taskId=u1fb7c291-b692-4a95-a137-9c31ba2eab7&title=&width=833)
  7. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/21416885/1643437687714-ebec22dd-39b8-45c2-a97b-f7746049bd88.png#clientId=u1c4c5315-4693-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=240&id=u08fa73cf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=479&originWidth=1448&originalType=binary&ratio=1&rotation=0&showTitle=false&size=120646&status=done&style=none&taskId=uaec34235-4722-4534-9fcf-e692ef09612&title=&width=724)
  8. <a name="F9XKp"></a>
  9. ## 代码
  10. <a name="WHqe7"></a>
  11. ### 抽象类

现金收费抽象类

abstract class CashSuper { //抽象方法。参数为原价,返回为当前价 public abstract double acceptCash(double money); }


<a name="pomVB"></a>
### 具体类

子类:正常收费

class CashNormal extends CashSuper { @override //正常收费,原价返回 public double acceptCash(double money) { return money; } }

子类:打折收费 class CashRebate extends CashSuper { private double moneyRebate = 1;

//打折收费,初始化时,需要输入折扣率 public CashRebate(string moneyRebate) { this.moneyRebate = double.Parse(moneyRebate); }

@override
public double acceptCash(double money)

{ return money * moneyrRebate; } }

子类:返利收费 class CashReturn extends CashSuper { private double moneyCondition = 0; private double moneyReturn = 0;

//返利收费,初始化时,输入返利条件和返利值,如满300返100 public CashReturn(string moneyCondition,string moneyReturn) { this.moneyCondition = double.Parse(moneyCondition); this.moneyReturn = double.Parse(moneyReturn); }

// @override public double acceptCash(double money) { double result = money; if (money >= moneyCondition) result = money - Math.Floor(money / moneyCondition) * moneyReturn; return result; } }


<a name="CxFYJ"></a>
### Context类

//CashContext类 class CashContext { private CashSuper cs;

public CashContext(CashSuper csuper) { this.cs = csuper; }

public double GetResult(double money) { return cs.acceptCash(money); } } ```

客户端代码
image.png

策略与简单工厂结合

策略模式中,仍然是在客户端去判断用哪一个算法,这样并不完美。可以与简单工厂结合,只修改Context类和客户端。
image.png

image.png

  1. 和简单工厂模式的主要区别在于:简单工厂模式下,主函数要使用工厂类和抽象类,但是策略模式下只用调用context类即可,相当于进一步的解耦,主函数与抽象类被完全分割开了。
  2. 在不同的场景使用不同的功能,这种变化一定会涉及switch,我们使用工厂类或context类封装了这种“变化”,把变化从主函数中独立出来。
  3. 每个算法都有自己的类,这简化了单元测试。

原则:单一职责、开放封闭、依赖倒转

单一职责

就一个类而言,应该仅有一个引起它变化的原因。

开放-封闭原则

软件实体(类、模块、函数)应该可以扩展,但不可以修改。

设计人员必须对于他设计的模块应该对哪种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。

面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。

拒绝不成熟的抽象和抽象本身一样重要。