前言
最近读了《深入浅出设计模式》–<<Head First设计模式>>,觉得挺有意思的一本书。作者写得也很风趣幽默。讲得通俗易懂。书的代码:我从github fork到了我的码云上。方便浏览https://gitee.com/goodshred/Head-First-Design-Patterns.git
定义
对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
个人理解
策略:就是以不变应万变的计策和战略
设计模式:是一种解决问题的思想或方案,而不是代码
打个比方
有这样一个需求:
请设计一个模拟现实生活中鸭子的游戏。游戏中会出现各种鸭子,在游泳,在呱呱叫。
通常的设计:
设计一个超类鸭子,然后让各种鸭子子类去继承超类
Class Duck{
quack(); //呱呱叫
swim(); //游泳
display() //外观(绿头的,红头的)
}
使用继承存在的问题:
1.代码在多个子类中重复
2.很难知道鸭子的全部行为
3.运行时的行为不容易改变
4.改变会牵一发而动全身,造成其他鸭子不想要的改变。
OO基础
抽象,封装,继承,多态
00原则
1.封装变化
2.多用组合,少用继承(通常“有一个”比“是一个”更好)
3.针对接口编程,不针对实现编程
需求变了
我们想让鸭子飞:
现实的情况是:鸭子的种类有红头的,绿头的,橡皮鸭…鸭子的行为有:会叫,会飞,会游泳 …,但橡皮鸭不会飞,橡皮鸭不是呱呱叫,而是吱吱叫。
采用策略模式的解决方案如下:
1.将多变的行为抽离出来设计成接口类:
public interface FlyBehavior {
void fly();
}
public interface QuackBehavior {
void quack();
//呱呱叫
}
2.设计一个实现类实现FlyBehavior接口
public class FlyByRocket implements FlyBehavior {
@Override
public void fly(){
System.out.println("坐着火箭飞");
}
}
//怎样飞:坐着火箭飞
3.设计模型鸭继承鸭子,并在模型鸭的构造方法中给flyBehavior接口类对象赋值
public class ModelDuck extends Duck{
public ModelDuck(){
flyBehavior=new FlyByRocket();
}
@Override
public void display(){
System.out.println("我是橡皮鸭!");
}
}
4.测试方法如下:
public class Main{
public static void main(String[] args) {
Duck duck=new ModelDuck();
duck.setFlyBehavior(new FlyByRocket());
duck.display();
duck.performFly();
}
}
运行结果:
总结L:这样设计以后,无论来什么样怪鸭子,无论需要鸭子有什么样的行为,我们的设计都可以很轻易的满足客户的需求。
总结
这是参照了https://blog.youkuaiyun.com/l_lhc/article/details/50685225
策略模式
- 简单来说:把解决一个问题的一组算法分派到抽象策略类的各个子类里面。通俗讲:对于同一个接口的同一个方法,不同的实现类对该方法有不同的重写方式(实现方案)。这可以叫做策略模式
- 举例1:经典的背包问题:你可以用贪心算法,回溯算法,动态规划算法等去解决。至于选择哪种算法是最好的,就要适具体情况而定。我们可以把这些算法都放在一个类里面。写一些if,else if去区分
如果使用了策略模式,PackageProblem类就会有三个子类–贪心算法类(里面有贪心算法函数),回溯算法类(回溯算法函数),动态规划算法类(里面有动态规划算法函数)public Class PackageProblem{ public int[] solve(){ if(该场景下贪心最好){ 贪心算法() } else if(该场景下回溯最好){ 回溯算法() } else{ 动态规划算法() } } }