永利皇宫手机版网址 > www.421.com > 设计模式 - 策略模式

原标题:设计模式 - 策略模式

浏览次数:63 时间:2019-11-23

前言:

  先不管格局, 把他和他的名字都忘了, 来看看问题 和 设计思路. 为什么要这么做. 

场景:

  有一家公司, 里面有二个营业员, 售货员当然是要卖东西的哇, 客商进来买完东西, 找售货员买单, 这售货员得驾驭一同多少钱吧?

风度翩翩. 初步设计

  商品类:

package org.elvin.strategy;

/***/
public class Goods {
    /**
     * 商品名
     */
    private String name;

    /**
     * 商品价格
     */
    private Long Price;

    public Goods() { }

    public Goods(String name, Long price) {
        this.name = name;
        Price = price;
    }

    //region getter / setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getPrice() {
        return Price;
    }

    public void setPrice(Long price) {
        Price = price;
    }
    //endregion
}

 

出于价格作者使用的是 Long 类型, 所以, 要有多少个转变输出的方法.

package org.elvin.strategy;

import java.text.MessageFormat;

public class MoneyUtils {
    public static String getYuan(Long money){
        Long yuan = money / 100;
        Long jiao = money % 100 /  10;
        Long fen = money % 10;

        return MessageFormat.format("{0}.{1}{2}", yuan, jiao , fen );
    }
}

设计模式 - 策略模式。售货员:

package org.elvin.strategy;

import org.elvin.strategy.calculator.*;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * 环境角色(Context)*/
public class Seller {

    /**
     * 姓名
     */
    private String name;

    /**
     * 编号
     */
    private String code;

    //region getter / setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
    //endregion

    /**
     * 售卖商品
     */
    public void sellGoods(List<Goods> goods){
        Long sum = 0L;
        for (Goods good : goods) {
            sum += good.getPrice();
        }
        System.out.println("应付款: " + MoneyUtils.getYuan(sum) + " 元");
    }

    @Test
    public void func1(){
        List<Goods> goods = new ArrayList<>();
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("饼干", 250L));
        goods.add(new Goods("辣条", 300L));

        sellGoods(goods);
    }
}

来看一下乘除结果:

图片 1

设计模式 - 策略模式。拿到结果了, 没啥毛病, 蛮好. 

前天老董过生辰, 溘然想到, 要不要再店里搞个移动, 来个减价活动, 有个别商品打折出售. 

次日业主过破壳日, CEO娘说, 老娘开心, 你降价出卖, 后天本人来个免单发卖.

那以后如何做吧? 不久前过后, 价格分明又要卷土重来到健康价格.  what the fuck! 

Seller类写死了, 难道作者在内部加多少个总括办法? 

加进去貌似可以解决当下主题材料, 不过, 后天倘若业主的娘亲属过生辰吗? 咋搞?

 

Ok, 到此处, 大概, 需求请出明日的大神 : 计谋方式. 让他来帮我们消亡这几个难题吧.

 

二. 设计改换

对此售货员来讲, 她必需知道, 今日该怎么总结价格, 是优化照旧不减价, 大概是满多少钱, 送东西怎么的. 

设计模式 - 策略模式。这就是说, 将那一个巨惠或然说价格的思量方式抽象出来, 成为三个接口恐怕抽象类. 

让打折也许不促销达成或然三回九转他.

落真实情状势:

此地, 作者将她抽象为叁个接口

package org.elvin.strategy.calculator;

import org.elvin.strategy.Goods;

import java.util.List;

/**
 * 抽象策略角色(Strategy)
 * 优惠接口
*/
public interface PreferentialPrice {
    public void getPrice(List<Goods> goods);
}

PreferentialPrice 需要作为一个属性,出现在 Seller 类中.

在Seller中加入

    /**
     * 计算优惠后的价格
     * 抽象角色, 次角色给出所有具体策略类所需的接口
     */
    private PreferentialPrice preferentialPrice;

    public PreferentialPrice getPreferentialPrice() {
        return preferentialPrice;
    }

    public void setPreferentialPrice(PreferentialPrice preferentialPrice) {
        this.preferentialPrice = preferentialPrice;
    }

 

此地提供二种计算方式:

  1. 例行形式

    /**

    • 实际战术角色(ConcreteStrategy) */ public class NoPreferential implements PreferentialPrice {

      @Override public void getPrice(List goods) {

       Long sum = 0L;
       for (Goods good : goods) {
           sum += good.getPrice();
       }
       System.out.println("应付款: " + MoneyUtils.getYuan(sum) + " 元");
      

      } }

  2. 免单情势

    /**

    • 切实政策剧中人物(ConcreteStrategy) */ public class Free implements PreferentialPrice { @Override public void getPrice(List goods) {
       System.out.println("免单, 不要钱 !");
      
      } }
  3. 一些降价情势

    /**

    • 实际政策角色(ConcreteStrategy) */ public class ReduceSomeGoods implements PreferentialPrice {

      @Override public void getPrice(List goods) {

       Long sum = 0L;
       for (Goods good : goods) {
           switch (good.getName()) {
               case "泡面":
                   sum += good.getPrice() - 50L;
                   break;
      
               case "火腿":
                   sum += good.getPrice() - 20L;
                   break;
      
               case "鸡蛋":
                   sum += good.getPrice() - 10L;
                   break;
      
               default:
                   sum += good.getPrice();
                   break;
           }
       }
       System.out.println("应付款: " + MoneyUtils.getYuan(sum) + " 元");
      

      } }

  

 将Seller类中, 总计的章程改正一下:

    public void sellGoods(List<Goods> goods){
        if(preferentialPrice == null){
            setPreferentialPrice(new NoPreferential());
        }
        preferentialPrice.getPrice(goods);
    }

在测算的时候, 若无传到减价, 则暗中同意使用无减价措施

再看测量检验方法:

    @Test
    public void func1(){
        List<Goods> goods = new ArrayList<>();
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("饼干", 250L));
        goods.add(new Goods("辣条", 300L));

        setPreferentialPrice(new Free());
        sellGoods(goods);
        System.out.println("-----------------------");
        setPreferentialPrice(new ReduceSomeGoods());
        sellGoods(goods);
        System.out.println("-----------------------");
        setPreferentialPrice(new NoPreferential());
        sellGoods(goods);
    }

结果:

  图片 2

战略形式作为风流倜傥种对象行为形式, 在这处应该如故展现到了吧.

那总计一下?给个不轻易精通(网络抄的):

  计策方式归属对象的一坐一起方式。其用意是本着风流倜傥组算法,将每三个算法封装到全部合作接口的独自的类中,进而使得它们能够互相替换。战术方式使得算法能够在不影响到客商端之处下爆发变化。

说的比较空虚, 来个实际的吧:

  生龙活虎帅哥喜欢约妹子, 那咋约出来啊? 不是享有的阿妹都欢愉进食看录制吧. 那针对不一致的妹子, 使用分歧的法子来约. 约喜欢看录制的大嫂看录制, 约喜欢吃小吃的胞妹吃小吃.

那吃饭, 看电影, 吹海风...... 等等, 那么些手法, 目标都认为着让三姐做他女对象(这里不商讨时间). 目标不改变, 花招不可胜举. 那么些办法, 就能够知道为不一致的 strategy. 

 

透过上边的例证, 能够看见, 具体的算法与算法之间向来不依靠关系, 都是同风姿浪漫的(平等性), 能够并行替换的. 那在运维的时候, 每趟都不能不使用风姿罗曼蒂克种(唯一性). 

本文由永利皇宫手机版网址发布于www.421.com,转载请注明出处:设计模式 - 策略模式

关键词:

上一篇:《若有缘,总会相见》

下一篇:将爱未爱,夏日荆棘