继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【学习打卡】第十天 Java设计模式精讲-Debug方式+内存分析 第十九讲

慕函数9884427
关注TA
已关注
手记 18
粉丝 1
获赞 4

【学习打卡】第十天 Java设计模式精讲-Debug方式+内存分析 第十九讲

课程名称:Java设计模式精讲-Debug方式+内存分析,真正学懂设计模式

课程章节: 策略模式+Coding+源码解析

主讲老师:Geely

课程内容:

今天学习的内容包括:

什么是策略模式   策略模式 优点 缺点  Coding  源码解析 以及在业务上的应用

课程收获:

  GOF的《设计模式》著作中认为策略模式可以消除一些条件语句,我对此持怀疑态度。正如上面的例子,虽然由于Context在初始化的时候已经指定了策略实现,在计算逻辑中不需要根据条件选择逻辑分支。但是,客户端代码在初始化Context的时候,如何判断应该传入哪个策略实现呢?其实在客户端代码或者别的地方还是缺少不了条件判断。所以这里消除条件语句,只是针对算法逻辑的条件判断。

 2. 策略模式优缺点

 那么策略模式的优点是什么了?

  2.1 优点

   1.  使用策略模式 可以根据策略接口 定义一系列可供复用的行为和算法;

   2.  调用方只需要持有context 的引用即可 而无需知道具体策略实现  满足迪米特法则; 

   3.  context在策略的方法之外可以做一些通用的切面逻辑

2.2 缺点

1. 客户端代码需要知道不同的策略以及如何选择策略。因此可以看到上面的客户端代码有着丑陋的条件判断;

2. 由于策略类实现同样的接口,所以参数列表要保持一致,但可能并不是所有的策略都需要全部参数

## 3. 策略模式与工厂模式结合使用

针对第一个缺点。我们可以通过策略模式与工厂模式结合使用来改进。通过进一步封装,消除客户端代码的条件选择

代码如下

package com.zw.design.pattern.behavioral.mianshi;
/****
 * 定义一个动物类的接口 实现策略
 */
public interface IAnimalStrategy {
    public void doPromotion() ;
}
package com.zw.design.pattern.behavioral.mianshi;
/***
 * 定义一个猫的类 实现动物的接口
 */
public class CatStrategy implements IAnimalStrategy {
    @Override
    public void doPromotion() {
        System.out.println("这个是处理猫的类");
    }
}
```
```java
package com.zw.design.pattern.behavioral.mianshi;
/***
 * 定义一个狗 实现动物策略接口
 */
public class DogStrategy implements IAnimalStrategy {
    @Override
    public void doPromotion() {
        System.out.println("处理dog行为");
    }
}


package com.zw.design.pattern.behavioral.mianshi;
/***
 * 定义一个空策略类 实现动物策略接口
 */
public class EmptyAnimalStrategy implements IAnimalStrategy {
    @Override
    public void doPromotion() {
    }
}


package com.zw.design.pattern.behavioral.mianshi;
/***
 * 这是pig 类实现动物策略接口类
 */
public class PigStrategy implements IAnimalStrategy {
    @Override
    public void doPromotion() {
        System.out.println("这是pig的类");
    }
}


package com.zw.design.pattern.behavioral.mianshi;
import java.util.HashMap;
import java.util.Map;
//这是一个抽象工厂 用来生产所有实现过策略模式的类
public abstract class AnimalStrategyFactory {
    //定义一个 静态的 常量的map 集合
    private final static Map<String, IAnimalStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, IAnimalStrategy>();
    //定义三个常量 并且是final 而且带分组功能
    private interface PromotionKey{
        String DOG = "dog";
        String PIG = "pig";
        String CAT = "cat";
    }
    /***
     * 根据你传入的key 返回一个具体促销的类 实现可扩展
     * @param promotionKey
     * @return
     */
    public static IAnimalStrategy getPromotionStrategy(String promotionKey){
        IAnimalStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
        // return promotionStrategy == null ? null : promotionStrategy;
        //为了业务 更友好的模式 这里不能返回null   所以定义一个无促销活动的类
        return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
    }
    //定义一个无促销的活动类
    private static final IAnimalStrategy NON_PROMOTION = new EmptyAnimalStrategy();
    //使用静态代码块进行往map 里面放入值 放入具体的策略的值
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.CAT,new CatStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.DOG,new DogStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.PIG,new PigStrategy());
    }
}


package com.zw.design.pattern.behavioral.mianshi;
/***
 * 使用策略模式的客户端 
 */
public class AnimalActivity {
    //放入动物策略的具体类 这里丢入接口 多态思想
    private IAnimalStrategy promotionStrategy;
    public AnimalActivity(IAnimalStrategy promotionStrategy){
        this.promotionStrategy = promotionStrategy;
    }
    //有个具体的行为
    public void executePromotionStrategy(){
        promotionStrategy.doPromotion();
    }
}
 //测试
public static void main(String[] args) {
        String petType="dog";
        AnimalActivity animalActivity=new AnimalActivity(
                AnimalStrategyFactory.getPromotionStrategy(petType)
        );
        animalActivity.executePromotionStrategy();
}


## 4. 策略模式适用场景


当存在多种逻辑不同,但属于同一类型的行为或者算法时,可以考虑使用策略模式。以此来消除你算法代码中的条件判断。同时让你的代码满足多种设计原则。


很多时候,工厂模式和策略模式都可以为你解决同类问题。但你要想清楚,你想要的是一个对象,还是仅仅想要一个计算结果。如果你需要的是一个对象,并且想用它做很多事情。那么请使用工厂模式。而你仅仅想要一个特定算法的计算结果,那么请使用策略模式。


策略模式属于对象行为模式,而工厂属于创建型模式。策略模式和工厂模式对比如下:

http://img1.mukewang.com/62f64dd600014e0511220604.jpg

 5. 小结

策略模式解决的问题是如何封装可供复用的算法或者行为。策略模式满足了单一职责、开闭、迪米特法则、依赖倒转等原则。我们一定想清楚策略模式的适用场景,否则某些时候你会搞不清到底用工厂模式还是策略模式。最后提醒大家,设计模式很多时候都是混合使用,我们不应该局限于使用某一种设计模式来解决问题。

## 6.jdk和spring当中具体典型案例

jdk Comparator 比较器最佳策略模式实现 

http://img4.mukewang.com/62f64e7a0001b53922581180.jpg

http://img4.mukewang.com/62f64ea10001572322880614.jpg

jdk TreeMap 当中 compare 方法也是策略模式的典型应用

http://img4.mukewang.com/62f64ebe0001552d11820324.jpg

Resource spring 当中 org.springframword.core.io 包下 当它实现类

我们可能经常用比如ClassPathResource还有文件FileSystemResource 

Spring 当中Bean的初始化也是用这个类 InstantiationStrategy 它的

实现类有两个  一个是Cglib的初始化类子类  

还有一个是简单的初始化策略 策略和策略之间可以存在继承关系

http://img3.mukewang.com/62f64ef50001e76210580390.jpg

http://img3.mukewang.com/62f64f200001ba1025760842.jpg

总结:今天学习课程共用了2个小时,重新学习一下设计模式 更加清楚知道策略模式的应用以及如何在自己项目当中去使用它  大家一起加油 💪🏻











打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP