首页 > 其他分享 >模板、策略以及工厂模式

模板、策略以及工厂模式

时间:2022-08-30 23:11:59浏览次数:75  
标签:BigDecimal 模式 工厂 Context Test new discountAmount public 模板

记录学习过程中的问题,实操总结,方便回顾。

模板方法

属于行为设计模式;
在父类中定义一个算法的框架,允许子类在不修改结果的情况下重写算法的特定步骤。
应用场景:当多个产品中的某一功能的处理重复,那么我们可以将重复的流程单独做成类方法(父类),然后针对每个产品继承父类并实现对应方法来适配不同的产品内部执行需求(子类)。

上述爬取不同网站的的数据,但是爬取和提取数据的流程一样,那么我们将重复的流程封装为父类方法,并实现。
好处:如果后续新加入不同产品的相同功能,那么可以直接拿来使用。
测试代码:

/**
注意使用京东类的时候进行了向上转型
*/
@Test
    public void demo(){
        NetMall netMall = new JDNetMall("1000001","*******");
        String base64 = netMall.generateGoodsPoster("https://item.jd.com/100008348542.html");
        log.info("测试结果:{}", base64);
    }

模板模式地址

策略模式

属于行为设计模式;
其能让你定义一系列算法并将每种算法分别放入独立的类中,以使算法的对象能够互换;
好处:能够替代大量if-else的利器;
场景:一般是具有同类可替代的行为逻辑算法场景;不同类型的交易方式(信用卡、支付宝、微信)、生成唯一ID策略(UUID、DB自增、DB+Redis、雪花算法、Leaf算法),导航软件(公路路线,步行路线,高速路线)等,都可以使用策略模式进行行为包装,供给外部使用;
其使用的核心点创建一个上下文策略类(策略控制器),并且必须包含一个成员变量来存储对于每种策略的引入:

/**
 * @author xbhog
 * @describe:策略控制器
 * @date 2022/8/21
 */
public class Context <T>{

    private ICouponDiscount<T> couponDiscount;

    public Context(ICouponDiscount<T> couponDiscount) {
        this.couponDiscount = couponDiscount;
    }
    public BigDecimal discountAmount(T couponInfo,BigDecimal skuPrice){
        return couponDiscount.discountAmount(couponInfo,skuPrice);
    }
}

通过构造方法来结构传递来的具体的策略,并调用计算接口。(真的很巧妙!!)上下文策略不负责选择具体的算法,相当于中间站,提供一个小屋来进行交互。

上下文策略使用的好处:上下文可独立于具体策略。这样你就可在不修改上下文代码或其他策略的情况下添加新算法或修改已有算法了。
看下测试(细品):

/**
     * 测试策略模式
     */
@Test
public void Strategy_mj(){
    Context<Map<String, String>> mjActivity = new Context<>(new MJCouponDiscount());
    HashMap<String, String> map = new HashMap<>();
    map.put("x","100");
    map.put("y","10");
    BigDecimal discountAmount = mjActivity.discountAmount(map, new BigDecimal(100));
    log.info("测试结果,满减优惠后的金额:{}",discountAmount);
}
@Test
public void Strategy_zj(){
    Context<Double> context = new Context<>(new ZjCouponDiscount());
    BigDecimal discountAmount = context.discountAmount(9D, new BigDecimal(100));
    log.info("测试结果,直减优惠后的金额:{}",discountAmount);
}
@Test
public void Strategy_zk(){
    Context<Double> context = new Context<>(new ZKCouponDiscount());
    BigDecimal discountAmount = context.discountAmount(0.8D, new BigDecimal(100));
    log.info("测试结果,折扣优惠后的金额:{}",discountAmount);
}
@Test
public void Strategy_nyg(){
    Context<Double> context = new Context<>(new NYGCouponDiscount());
    BigDecimal discountAmount = context.discountAmount(80D, new BigDecimal(100));
    log.info("测试结果,N元购优惠后的金额:{}",discountAmount);
}

策略模式地址

工厂方法模式

属于创建型设计模式;
工厂模式在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型;
好处:提供代码的扩展性,减少if-else方法
场景:

  1. 当我们需要替换新的对象时,但是在不同的产品或功能中都引入了,造成修改困难;(简单工厂模式,但功能过多时,会造成过多的if-else)
  2. 当我们需要增加新的对象,比如奖品(兑换卡,实物商品,优惠卷)或者日志框架等类型的场景(工厂方法模式)

工厂方法模式的核心:调整对象创建时的位置,但是需要注意的是,仅当这些产品(兑换卡,实物商品,优惠卷)具有相同的父类或者接口时,子类才能返回不同类型的产品,同时父类中的工厂方法还应将其返回类型声明为这一共有接口(每个产品具有共同的方法);
参考图如下:

细品测试:

/**
     * 工厂模式
     * @throws Exception
     */
    @Test
    public void  test_commodity() throws Exception{
        StoreFactory storeFactory = new StoreFactory();
        ICommodity commodityService = storeFactory.getCommodityService(3);
        commodityService.sendCommodity("10001","AQY1xjkUodl8LO975GdfrYUio",null,null);
    }
    @Test
    public void Test_coupon() throws Exception {
        StoreFactory storeFactory = new StoreFactory();
        ICommodity commodityService = storeFactory.getCommodityService(1);
        commodityService.sendCommodity("10001", "EGM1023938910232121323432", "791098764902132", null);
    }
    @Test
    public void Test_Goods() throws Exception {
        StoreFactory storeFactory = new StoreFactory();
        ICommodity commodityService = storeFactory.getCommodityService(2);
        HashMap<String, String> extMap = new HashMap<>();
        extMap.put("consigneeUserName", "谢飞机");
        extMap.put("consigneeUserPhone", "15200292123");
        extMap.put("consigneeUserAddress", "吉林省.长春市.双阳区.XX街道.檀溪苑小区.#18-2109");
        commodityService.sendCommodity("10001","9820198721311","1023000020112221113",extMap);
    }

推荐博客
工厂方法模式地址

参考和学习引用

深入设计模式(亚历山大·什韦茨)
重学Java设计模式

标签:BigDecimal,模式,工厂,Context,Test,new,discountAmount,public,模板
From: https://www.cnblogs.com/xbhog/p/16641298.html

相关文章

  • 静态——字段与属性、方法与类、单例设计模式
    1、static关键字static关键字,用于修饰类,字段,属性,方法,构造方法等。被static修饰的类称之为“静态类”;被static修饰的成员称之为“静态成员”;被修饰过的成员分别称为:......
  • Story shopify主题模板配置修改
    shopifystory主题是一个旨在发展你的品牌和建立客户信任的主题,非常适用于珠宝和饰品、食品和饮料、服装、家居和装饰、电子产品、书籍、音乐和视频、健康和美容、运动和娱......
  • 单例模式
    单例模式是什么?为什么要使用单例模式单例模式,顾名思义就是在整个运行时域,一个类只有一个实例对象为什么要用单例呢。因为有的类的,比较庞大和复杂,如果频繁创建和销毁对象,......
  • C# 装饰模式
    //Seehttps://aka.ms/new-console-templateformoreinformation/**个人理解你要往原有的东西上加东西Phone=装饰手机原材料Decorator=装饰手机中间人Xiao......
  • Shopify主题Lorenza模板配置修改
    Lorenza是为时尚零售商提供的一个精品shopify主题,有了一个大型的导航和先进的产品过滤,Lorenza现在非常适合大中型产品目录。Lorenza背后的指导思想是使用不对称性和编辑功......
  • C嵌入式编程设计模式-C语言类实现方式
    类的封装方式以文件作为封装边界,将外部调用的函数声明,全局变量变量放入头文件中,将具体实现放入.c文件中。简单栈的实现代码:/************************************......
  • Python面向对象模板
    内容概要面向对象面向对象前戏对象与类的创建对象独有的数据对象独有的功能动静态方法面向对象三大特性之继承面向对象三大特性之封装property伪装属性面向对象三大......
  • C++11可变参数模板(函数模板、类模板)
    https://yngzmiao.blog.csdn.net/article/details/105247065......
  • js 严格模式
    //js使用严格模式可以规范我们写代码//要启用严格模式,您只需要在JavaScript脚本的开头添加"usestrict";或'usestrict';指令即可,如下所示:<script>"usestrict";......
  • ACM模式输入处理
    字符串输入遇到空格问题cin遇到空格会停止输入一句英文,存入一个字符串使用:getline(cin,s)例如:iamaboygetline是碰到终止符才停止如果你要把一个个单词存成一......