策略模式的定义:
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
策略模式的理解
我们以三国时期刘关张去商场买东西来为例讲解(大哥刘备是皇室草鞋的至尊vip用户,二哥关羽是皇室草鞋的vip客户,三弟张飞是皇室草鞋的老用户)
欢迎光临皇室草鞋
本店具有优惠政策如下
至尊vip客户 享受全场商品七折优惠
vip客户 享受全场商品八折优惠
老用户 享受全场商品九折优惠
接到项目开发皇室草鞋
年轻的朋友啊 要是你们会怎么来开发呢。
public BigDecimal quote(BigDecimal originalPrice,String customType){
if ("老用户".equals(customType)) {
System.out.println("恭喜你!享受全场商品九折优惠!");
originalPrice = originalPrice.multiply(new BigDecimal(0.9)).setScale(2,BigDecimal.ROUND_HALF_UP);
return originalPrice;
}else if ("vip客户".equals(customType)) {
System.out.println("恭喜你!享受全场商品八折优惠");
originalPrice = originalPrice.multiply(new BigDecimal(0.8)).setScale(2,BigDecimal.ROUND_HALF_UP);
return originalPrice;
}else if("至尊vip客户".equals(customType)){
System.out.println("恭喜你!享受全场商品七折优惠");
originalPrice = originalPrice.multiply(new BigDecimal(0.7)).setScale(2,BigDecimal.ROUND_HALF_UP);
return originalPrice;
}
//其他人员都是原价
return originalPrice;
}
年轻的朋友啊 不错不错 你能独立完成皇室草鞋的项目了。但是!
上面存在的问题:把不同客户的报价的算法都放在了同一个方法里面,使得该方法很是庞大(现在是只是一个演示,所以看起来还不是很臃肿)。
下面看一下上面的改进,我们把不同客户的报价的算法都单独作为一个方法
改进!!!
首先我们创建一个草鞋的抽象类 由具体的类的继承 这里我们就用皇室草鞋来继承(以后或者会开更多的分店呢)
public abstract class AbstractStrawSandals {
/**
* 说不定以后需要开分店
*/
abstract void storeName();
}
创建算法的接口
public interface DiscountsBehavior {
/**
* 算法公共接口
* @param originalPrice 原价
* @return BigDecimal
*/
BigDecimal getPrice (BigDecimal originalPrice);
}
实现各种算法
九折优惠
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public class NineDiscount implements DiscountsBehavior {
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
originalPrice = originalPrice.multiply(new BigDecimal(0.9)).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("享受后的折扣价为"+originalPrice);
return originalPrice;
}
}
八折优惠
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public class EightDiscount implements DiscountsBehavior{
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
originalPrice = originalPrice.multiply(new BigDecimal(0.8)).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("享受后的折扣价为"+originalPrice);
return originalPrice;
}
}
七折优惠
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public class SevenDiscount implements DiscountsBehavior {
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
originalPrice = originalPrice.multiply(new BigDecimal(0.7)).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("享受后的折扣价为"+originalPrice);
return originalPrice;
}
}
现在我们来改进抽象类实列化算法接口
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public abstract class AbstractStrawSandals {
//所以的算法都继承于它
DiscountsBehavior discountsBehavior;
public void discounts(BigDecimal originalPrice) {
//委托给行为类
discountsBehavior.getPrice(originalPrice);
}
/**
* 说不定以后需要开分店
*/
abstract void storeName();
//为了在运行过程中随意切换折扣
public void setDiscountsBehavior(DiscountsBehavior discountsBehavior) {
this.discountsBehavior = discountsBehavior;
}
}
现在完成老用户vip 和至尊vip的打折优惠
老用户
package com.smile.design.strategy.strategyJob3;
/**
* @author smile
* @date 2019-06-24
*/
public class OldUser extends AbstractStrawSandals {
public OldUser(){
//九折优惠
discountsBehavior = new NineDiscount();
}
@Override
void storeName() {
System.out.println("皇室草鞋总店");
}
}
Vip用户
package com.smile.design.strategy.strategyJob3;
/**
* @author smile
* @date 2019-06-24
*/
public class VipUser extends AbstractStrawSandals {
public VipUser () {
//八折优惠
discountsBehavior = new EightDiscount();
}
@Override
void storeName() {
System.out.println("皇室草鞋总店");
}
}
至尊Vip用户
package com.smile.design.strategy.strategyJob3;
/**
* @author smile
* @date 2019-06-24
*/
public class SupremacyVipUser extends AbstractStrawSandals {
public SupremacyVipUser () {
//七折优惠
discountsBehavior = new SevenDiscount();
}
@Override
void storeName() {
System.out.println("皇室草鞋总店");
}
}
现在我们来买鞋子把
刘关张三人一齐来的皇室草鞋总店,呀!!! 三弟惊呼道:大哥你看这双鞋肯定很如意你的美脚。 大哥刘备看了一眼 连忙把鞋子拿起来赞道:世间居然还有如此般配的美脚的鞋 连忙叫服务员拿了一试。 舒服!舒服!舒服! 哈哈哈哈哈哈 大哥刘备呼喊道。 来到结帐台
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public class DiscountTest {
public static void main(String[] args) {
AbstractStrawSandals strawSandals = new SupremacyVipUser();
strawSandals.storeName();
strawSandals.discounts(new BigDecimal(1000));
}
}
输出为:
皇室草鞋总店
享受后的折扣价为700.00
服务员:先生您好 您是我们店的至尊Vip用户享受我们店里的七折优惠 折后 700元整
张飞:呆 你这个蠢牛 知道我大哥是谁吗 可是皇家的亲戚 居然还要700元便宜点500算了,不便宜跟你把店拆咯
服务员:原来是刘备兄 失敬失敬 那在下就跟您打个五折好了(其实心里吗卖批)
刘备:三弟不可无礼,(其实心里笑开了花,哈哈)
刘备的五折优惠
刚刚经过张飞的折腾 现在又有了五折优惠 该如何变动呢
首先实现公共折扣的接口,再开一个牛黄叔的专用通道 是否也!
五折!!
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public class FiveDisCount implements DiscountsBehavior {
@Override
public BigDecimal getPrice(BigDecimal originalPrice) {
originalPrice = originalPrice.multiply(new BigDecimal(0.5)).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("牛黄叔的专用通道 享受后的折扣价为"+originalPrice);
return originalPrice;
}
}
改动测试类
package com.smile.design.strategy.strategyJob3;
import java.math.BigDecimal;
/**
* @author smile
* @date 2019-06-24
*/
public class DiscountTest {
public static void main(String[] args) {
AbstractStrawSandals strawSandals = new SupremacyVipUser();
strawSandals.storeName();
strawSandals.setDiscountsBehavior(new FiveDisCount());
strawSandals.discounts(new BigDecimal(1000));
}
}
输出接口为:
皇室草鞋总店
牛黄叔的专用通道 享受后的折扣价为500.00
设计原则
多用组合,少用继承
使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以运行时动态地改变行为,只用组合的行为对象符合正确的接口与标准即可
网友评论