【源码分析设计模式 11,Java高级视频教程

}

}




4、打折收费子类

--------



package designMode.strategy;

public class CashRebate extends CashSuper {

private double moneyRebate = 0.8;



public CashRebate(double moneyRebate) {

    this.moneyRebate = moneyRebate;

}



@Override

public double acceptCash(double money) {

    return money*moneyRebate;

}

}




5、返利收费子类

--------



package designMode.strategy;

public class CashReturn extends CashSuper {

private double moneyConditation = 0.0;

private double moneyReturn = 0.0d;



public CashReturn(double moneyConditation, double moneyReturn) {

    this.moneyConditation = moneyConditation;

    this.moneyReturn = moneyReturn;

}



@Override

public double acceptCash(double money) {

    double result = money;

    if(money>moneyConditation){

        result = money-Math.floor(money/moneyConditation)*moneyReturn;

    }

    return result;

}

}




6、client客户端

-----------



package designMode.strategy;

import java.util.Scanner;

public class Client {

public static void main(String[] args) {

    CashContext cashContext = null;

    Scanner scanner = new Scanner(System.in);

    System.out.println("请输入打折方式(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 += "打八折";

            break;

        default:

            System.out.println("请输入1/2/3");

            break;

    }

    double totalPrices = 0;

    System.out.print("请输入单价:");

    double price = scanner.nextDouble();

    System.out.println("请输入数量:");

    double num = scanner.nextDouble();

    totalPrices = cashContext.getResult(price * num);

    System.out.println("单价:" + price + ",数量:" + num + ",类型:" + type + ",合计:" + totalPrices);

    scanner.close();

}

}




7、运行结果

------



![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9vc2NpbWcub3NjaGluYS5uZXQvb3NjbmV0L3VwLTdjMWM4NzljNDUzZGFmMDE5ZmExYWEzMTkwYjUzYjc5ZjQ2LnBuZw?x-oss-process=image/format,png)



![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9vc2NpbWcub3NjaGluYS5uZXQvb3NjbmV0L3VwLTIwMzk2YmMwNjkwNGEzMjUzNzgyNjUxOGFkMThhYjUzMTlkLnBuZw?x-oss-process=image/format,png)



![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9vc2NpbWcub3NjaGluYS5uZXQvb3NjbmV0L3VwLWIyYzIyNjUyMmU2ZTJlYjMzMzQ5YjI2MzBhM2U0YjJjYTEyLnBuZw?x-oss-process=image/format,png)



**五、策略模式与工程模式的区别**

==================



1、策略模式是行为性模式,适应行为的变化 ,强调父类的调用子类的特性 。



工厂模式是创建型模式,适应对象的变化,强调统一接口 。



2、策略模式封装行为,调用的时候必须先制定实例化具体的类,再调用抽象的方法; 策略模式的作用是让一个对象在许多行为中选择一种行为。



工厂模式封装对象,实例化对象后调用的时候要知道具体的方法。



3、策略模式是调用不同类方法, 工厂模式是对父类进行重写。



这俩个模式本来就是解决类似的问题,可以说是孪生兄弟,且内部实现都差不多,都是通过子类来覆盖父类而已,不过简单工厂是把父类直接摆在客户端,而策略模式是将父类隐藏在Context里面,这样封装更好。



4、举个例子  

(1)产品之于加减乘除,水果之于苹果梨橘子香蕉,文具之于笔尺刀,这时产品比较具体、有限和没有多个算法重叠,这时实用简单工厂模式。  

(2)产品之于商场促销中的返利(可为300返100、500返200、10000返500等等无数)、折扣(2折、2.5折、6折、9折、9.1折等等无数)、正常购买、消费积分(100元10积分、200元30积分等等无数),这时产品构造又多次重叠,且有在不同时刻应用不同的规则时使用策略模式。



5、总结



简单工厂模式只是解决了对象的创建问题,工厂需要包括所有的产品对象的创建,如果产品对象形式经常变化,就需要经常改动工厂,以致代码重新编译。所以策略模式就诞生了,策略模式---它定义了算法家族,分别封装起来,而不是像简单产品模式一样定义所有的产品类,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户,使客户拥有相同的访问过程。  

简单工厂模式的核心是“简单工厂模式就是用来封装所有的产品对象的”。



![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMjgwMDQ0LzIwMTgwOC8yODAwNDQtMjAxODA4MjAxMTQ0NTg2ODMtMTI1MDQ2ODAwOC5qcGc?x-oss-process=image/format,png)



策略模式理解核心是“策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中遇到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性”。



![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDE4LmNuYmxvZ3MuY29tL2Jsb2cvMTAxODc3MC8yMDE5MDYvMTAxODc3MC0yMDE5MDYxMjE3MjAzNTMxNi01MDc3NjM5MzAucG5n?x-oss-process=image/format,png)



在基本的策略模式中,选择所用的具体实现的算法的职责由客户端对象承担,并转给策略模式的Context对象。这是策略模式本身纯粹的定义,所以,“选择所用最终怎样处理”还有很多文章可做。  

看了课本之后对于这两个模式还是有很多不理解的地方,但是相信随着对设计模式进一步的学习,能够更好地体会到这其中的奥妙,学习是一个循序渐进的过程。



六、SpringMVC中的策略模式

=================



1、getDefaultStrategies

----------------------



在DispatchServlet中的初始化组件中,用到了getDefaultStrategies方法,来决定不同组件的默认类型以实现组件的初始化操作。



// 传入ApplicationContext上下文和策略接口的Class类型

protected List getDefaultStrategies(ApplicationContext context, Class strategyInterface) {

// 相应组件的类名

String key = strategyInterface.getName();

// 从property中获取当前策略接口实现类的类名集合

String value = defaultStrategies.getProperty(key);

if (value != null) {

    // 获取策略接口所有实现类的类名

    String[] classNames = StringUtils.commaDelimitedListToStringArray(value);

    List<T> strategies = new ArrayList<T>(classNames.length);

    for (String className : classNames) {

        try {

            // 创建相应实现类的bean,并放入集合中

            Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());

            Object strategy = createDefaultStrategy(context, clazz);

            strategies.add((T) strategy);

        }

        catch (ClassNotFoundException ex) {

            throw new BeanInitializationException(

                    "Could not find DispatcherServlet's default strategy class [" + className +

                            "] for interface [" + key + "]", ex);

        }

        catch (LinkageError err) {

            throw new BeanInitializationException(

                    "Error loading DispatcherServlet's default strategy class [" + className +

                            "] for interface [" + key + "]: problem with class file or dependent class", err);

        }

    }

    // 返回策略接口实现类的集合

    return strategies;

}

else {

    return new LinkedList<T>();

}

}


// 初始化真正调用的重载方法,默认返回策略实现类的第一个

protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {

    List<T> strategies = getDefaultStrategies(context, strategyInterface);

    if (strategies.size() != 1) {

        throw new BeanInitializationException(

                "DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");



# 面试结束复盘查漏补缺

每次面试都是检验自己知识与技术实力的一次机会,面试结束后建议大家及时总结复盘,查漏补缺,然后有针对性地进行学习,既能提高下一场面试的成功概率,还能增加自己的技术知识栈储备,可谓是一举两得。

**以下最新总结的阿里P6资深Java必考题范围和答案**,包含最全MySQL、Redis、Java并发编程等等面试题和答案,用于参考~

**资料免费领取方式:点赞关注后,[戳这里免费领取](https://gitee.com/vip204888/java-p7)**

**重要的事说三遍,关注+关注+关注!**

![历经30天,说说我的支付宝4面+美团4面+拼多多四面,侥幸全获Offer](https://img-blog.csdnimg.cn/img_convert/6f30479c1848c32237c8119c5cc4945a.png)

![image.png](https://img-blog.csdnimg.cn/img_convert/1615fae90471a682ea77aeb21687caf5.png)



**更多笔记分享**

");



# 面试结束复盘查漏补缺

每次面试都是检验自己知识与技术实力的一次机会,面试结束后建议大家及时总结复盘,查漏补缺,然后有针对性地进行学习,既能提高下一场面试的成功概率,还能增加自己的技术知识栈储备,可谓是一举两得。

**以下最新总结的阿里P6资深Java必考题范围和答案**,包含最全MySQL、Redis、Java并发编程等等面试题和答案,用于参考~

**资料免费领取方式:点赞关注后,[戳这里免费领取](https://gitee.com/vip204888/java-p7)**

**重要的事说三遍,关注+关注+关注!**

[外链图片转存中...(img-g9DjlWRF-1628391070300)]

[外链图片转存中...(img-hFR7u39V-1628391070302)]



**更多笔记分享**

![历经30天,说说我的支付宝4面+美团4面+拼多多四面,侥幸全获Offer](https://img-blog.csdnimg.cn/img_convert/80c213c690bd5aa94c079377aa5e1a95.png)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值