java 策略模式缺点,Java 设计模式之策略模式

策略模式简介

定义

定义一系列的算法,把每一个算法封装起来,并且使它们可以相互替换。策略模式能使算法与用户端而独立存在与变化。

例子

某商场为迎接国庆的到来,决定开启商品促销活动,活动细节如下

针对不同会员等级优惠的折扣有所不同,同时与消费金额所关联,消费金额在不同范围折扣优惠率也不一样。

普通会员:没有任何优惠折扣

初级会员:消费100-200元有5%的促销折扣,消费200(含200)以上元有10%促销折扣

中级会员:消费100-200元有10%的促销折扣,消费200(含200)以上元有15%促销折扣

高级会员:消费100-200元有15%的促销折扣,消费200(含200)以上元有20%促销折扣

最后需计算促销折扣后,实付金额。

为了实现上面的需求,通常我们会这样写,如下:

public class StragetyTest {

public static void main(String[] args) {

StragetyTest test = new StragetyTest();

test.getPayAmount("初级会员", 150);

test.getPayAmount("中级会员", 150);

test.getPayAmount("高级会员", 150);

}

public double getPayAmount(String memberType, double amount) {

double payAmout=0;

switch (memberType) {

case "初级会员":

if (amount>=100 && amount<200 ) {

//促销折扣5%

payAmout=amount*0.95;

}else if (amount>=200) {

//促销折扣10%

payAmout=amount*0.9;

}else {

//没有优惠折扣

payAmout=amount;

}

break;

case "中级会员":

if (amount>=100 && amount<200 ) {

//促销折扣10%

payAmout=amount*0.9;

}else if (amount>=200) {

//促销折扣15%

payAmout=amount*0.85;

}else {

//没有优惠折扣

payAmout=amount;

}

break;

case "高级会员":

if (amount>=100 && amount<200 ) {

//促销折扣15%

payAmout=amount*0.85;

}else if (amount>=200) {

//促销折扣20%

payAmout=amount*0.8;

}else {

//没有优惠折扣

payAmout=amount;

}

break;

default:

//没有优惠折扣

payAmout=amount;

break;

}

System.out.println("原价:"+amount+"元,"+memberType+"优惠后的实际价格:"+payAmout+"元");

return payAmout;

}

}

上面的代码,需求倒是实现了,如果活动促销规则临时有变,需要对普通会员消费有促销力度……此时就在增加对普通会员优惠金额的计算了,在原代码需增加if-else判断语句了,如果每个会员等级的商品促销折扣算法变的更复杂,各种判断语言交错其中,那么代码就会变的特别浮肿,后期维护扩展困难,增加开发的成本。这可违背了设计模式中的单一职责原则。

下面通过策略模式,进行重构。如下:

1、定义一个用于计算促销折扣后的实际价格的接口(策略接口)

public interface MemberStrategy {

double getPayAmount(double amount);

}

2、分别定义三个会员等级的具体产品类,它们共同的特点实现了计算促销优惠后的价格(具体策略实现)

//初级会员

public class PrimaryMemberStrategy implements MemberStrategy{

@Override

public double getPayAmount(double amount) {

double payAmout;

if (amount>=100 && amount<200 ) {

//促销折扣5%

payAmout=amount*0.95;

}else if (amount>=200) {

//促销折扣10%

payAmout=amount*0.9;

}else {

//没有优惠折扣

payAmout=amount;

}

System.out.println("原价:"+amount+"元,初级会员优惠后的实际价格:"+payAmout+"元");

return payAmout;

}

}

//中级会员

public class MiddleMemberStrategy implements MemberStrategy{

@Override

public double getPayAmount(double amount) {

double payAmout;

if (amount>=100 && amount<200 ) {

//促销折扣10%

payAmout=amount*0.9;

}else if (amount>=200) {

//促销折扣15%

payAmout=amount*0.85;

}else {

//没有优惠折扣

payAmout=amount;

}

System.out.println("原价:"+amount+"元,中级会员优惠后的实际价格:"+payAmout+"元");

return payAmout;

}

}

//高级会员

public class AdvancedMemberStrategy implements MemberStrategy{

@Override

public double getPayAmount(double amount) {

double payAmout;

if (amount>=100 && amount<200 ) {

//促销折扣15%

payAmout=amount*0.85;

}else if (amount>=200) {

//促销折扣20%

payAmout=amount*0.8;

}else {

//没有优惠折扣

payAmout=amount;

}

System.out.println("原价:"+amount+"元,高级会员优惠后的实际价格:"+payAmout+"元");

return payAmout;

}

}

3、定义一个控制器,包含了每个会员等级,可以传递不同具体会员对象来调用需要的方法。

public class MemberContext {

private MemberStrategy mStrategy;

//使用多态来接受对象值。

public void setMemberStrategy(MemberStrategy mStrategy) {

this.mStrategy = mStrategy;

}

public double getPayAmount(double amount){

return mStrategy.getPayAmount(amount);

}

}

4、用户使用

public class StragetyTest {

public static void main(String[] args) {

MemberContext memberContext = new MemberContext();

//初级会员

memberContext.setMemberStrategy(new PrimaryMemberStrategy());

memberContext.getPayAmount(150);

//中级会员

memberContext.setMemberStrategy(new MiddleMemberStrategy());

memberContext.getPayAmount(150);

//高级会员

memberContext.setMemberStrategy(new AdvancedMemberStrategy());

memberContext.getPayAmount(150);

}

}

最后的结果:

原价:150.0元,初级会员优惠后的实际价格:142.5元

原价:150.0元,中级会员优惠后的实际价格:135.0元

原价:150.0元,高级会员优惠后的实际价格:127.5元

可以看出,使用策略模式,把每个会员等级促销算法独立出来,互不影响,也避免了对会员等级switch-case判断语句,降低了代码的耦合性,有利于维护,即使增加对普通会员的促销策略,也无需改动原来的代码,只需新增策略具体类即可,不仅体现了设计模式中职责单一原则,还体现了开放封闭原则,

同时缺点也会明显,如果策略过多,会增加过多的策略类,最后导致类的数量剧增。

针对上面的策略模式的例子,用UML类图体现如下:

UML结构图

b0849949-820a-4bf6-82ab-7f67edfe3551.png

角色介绍:

MemberStrategy:抽象策略角色,算法方法的抽象,通常是接口

Strategy:具体策略类,实现了抽象策略接口,算法的具体实现。

MemberContext:上下文角色,用来操控每个策略类的上下文环境。屏蔽了高层模块对具体算法的访问,提现了设计模式中的依赖倒置原则。

使用场景

在开发中,凡是有同类型类似的算法需求,可以尝试使用策略模式进行封装来应对不同的变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值