小工具知识网

当前位置: 首页 > 行业知识 > 设计模式--策略模式和责任链模式

行业知识

设计模式--策略模式和责任链模式

2026-10-21 11:09:26 来源:互联网转载

策略模式

���略模式(Strategy Pattern)又叫做政策模式,它是将定义的算法家族、分别包装起来,让它们之间可以相互替换,从而让算法的变化不会影响到使用算法的用户。属于行为型模式。

()

策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同实现。

应用场景:

()
  • 针对同一类型问题,有多种处理方式,每一种都能独立解决问题;
  • 算法需要自由切换的场景;
  • 需要屏蔽算法规则的场景;
    /** * 促销策略抽象 */interface IPromotionStrategy{    void doPromotion();}class CouponbuyStrategy implements IPromotionStrategy{    @Override    public void doPromotion() {        System.out.println("使用优惠卷抵扣");    }}class CashbackStrategy implements IPromotionStrategy{    @Override    public void doPromotion() {        System.out.println("返现");    }}class EmptyStrategy implements IPromotionStrategy{    @Override    public void doPromotion() {        System.out.println("无优惠");    }}class PromotionActivity{    private IPromotionStrategy strategy;    public PromotionActivity(IPromotionStrategy strategy) {        this.strategy = strategy;    }    public void excute(){        strategy.doPromotion();    }}public class Test {    public static void main(String[] args) {        PromotionActivity activity618 = new PromotionActivity(new CouponbuyStrategy());        PromotionActivity activity1111 = new PromotionActivity(new CashbackStrategy());        activity618.excute();        activity1111.excute();    }}//public class Test {//    public static void main(String[] args) {//        PromotionActivity activity = null;////        String promotionKey = "COUPON";////        if(promotionKey.equals("COUPON")){//            activity = new PromotionActivity(new CouponbuyStrategy());//        }else if(promotionKey.equals("CASHBACK")){//            activity = new PromotionActivity(new CashbackStrategy());//        }////        activity.excute();//    }//}

    我们可以结合单例模式和工厂模式优化上述代码:

    class PromotionStrategyFactory{    private static Map PROMOTIONS = new HashMap();    private interface PromotionKey{        String COUPON = "COUPON";        String CASHBACK = "CASHBACK";    }    static {        PROMOTIONS.put(PromotionKey.COUPON,new CouponbuyStrategy());        PROMOTIONS.put(PromotionKey.CASHBACK,new CashbackStrategy());    }    private static final IPromotionStrategy EMPTY = new EmptyStrategy();    private PromotionStrategyFactory(){}    public static IPromotionStrategy getPromotionStrategy(String promotionKey){        IPromotionStrategy strategy = PROMOTIONS.get(promotionKey);        return strategy==null?EMPTY:strategy;    }    public static Set getPromotionKeys(){        return PROMOTIONS.keySet();    }}public class Test {    public static void main(String[] args) {        String promotionKey = "COUPON";        IPromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);        promotionStrategy.doPromotion();    }}

    策略模式的优缺点:

    优点:

    1. 策略模式符合开闭原则
    2. 避免使用多重条件转移语句,如if..else...语句、switch语句
    3. 使用策略模式可以提高算法的保密性和安全性

    缺点

    1. 客户端必须知道所有的策略,并且自行决定使用哪个策略类
    2. 代码中会产生非常多策略类,增加维护难度。

    责任链模式

    责任链模式(Chain of Responsibility Pattern)是将链中每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护一个下一节点对象。当一个请求从链式的首端出发时,会沿着链的路径依次传递给每一个对象,直至有对象处理这个请求为止。属于行为模式。

    责任链模式主要是解耦了请求与处理,客户只需要将请求发送到链上即可,无需关心请求的具体内容和处理细节,请求会自动进行传递直至有节点对象进行处理。适用于以下应用场景:

    • 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定;
    • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
    • 可动态指定一组对象处理请求。

      利用责任链模式进行数据校验拦截:

      import lombok.Data;import org.junit.platform.commons.util.StringUtils;@Dataclass Member{    private String loginName;    private String loginPass;    private String roleName;    public Member(String loginName, String loginPass) {        this.loginName = loginName;        this.loginPass = loginPass;    }}/** * 臃肿的代码 */class MemberService{    public void login(String loginName,String loginPass){        if(StringUtils.isBlank(loginName) || StringUtils.isBlank(loginPass)){            System.out.println("登录信息不能为空");        }        Member member = checkExists(loginName,loginPass);        if(member == null){            System.out.println("用户不存在");        }        if(!"管理员" .equals(member.getRoleName())){            System.out.println("用户权限不够");        }        System.out.println("登录成功");    }    private Member checkExists(String loginName, String loginPass){        Member member = new Member(loginName,loginPass);        member.setRoleName("管理员");        return member;    }}/** * 利用责任链优化代码 */abstract class  Handler{    protected Handler chain;    public void next(Handler handler){        this.chain = handler;    }    public abstract void doHandle(Member member);}/** * 为空校验 */class ValidateHandler extends Handler{    @Override    public void doHandle(Member member) {        if(StringUtils.isBlank(member.getLoginName()) || StringUtils.isBlank(member.getLoginPass())){            System.out.println("登录信息不能为空");            return;        }        chain.doHandle(member);    }}class LoginHandler extends Handler{    @Override    public void doHandle(Member member) {        /**         * 查询用户是否存在         */        System.out.println("登录成功");        member.setRoleName("管理员");        chain.doHandle(member);    }}/** * 权限验证 */class AuthHandler extends Handler{    @Override    public void doHandle(Member member) {        if(!"管理员".equals(member.getRoleName())){            System.out.println("权限不够");            return;        }        System.out.println("登录成功");    }}class MemberService2{    public void login(String loginName,String loginPass){        ValidateHandler validateHandler = new ValidateHandler();        LoginHandler loginHandler = new LoginHandler();        AuthHandler authHandler = new AuthHandler();        validateHandler.next(loginHandler);        loginHandler.next(authHandler);        validateHandler.doHandle(new Member(loginName,loginPass));    }}public class Test {    public static void main(String[] args) {        MemberService memberService = new MemberService();        memberService.login("tom","666");        MemberService2 memberService2 = new MemberService2();        memberService2.login("tom","666");    }}

      另外,链式的组装过于复杂,可以建造者模式处理节点对象进行自动链式组装。处理节点对象顺序不同,构造出来的链式结构也随之不同。修改后的代码:

      /** * 利用责任链优化代码 */abstract class  Handler{    protected Handler chain;    public void next(Handler handler){        this.chain = handler;    }    public abstract void doHandle(Member member);    public static class Builder{        private Handler head;        private Handler tail;        public Builder addHandler(Handler handler){            if(this.head == null){                this.head = this.tail = handler;                return this;            }            this.tail.next(handler);            this.tail=handler;            return this;        }        public Handler build(){            return this.head;        }    }}class MemberService2{    public void login(String loginName,String loginPass){//        ValidateHandler validateHandler = new ValidateHandler();//        LoginHandler loginHandler = new LoginHandler();//        AuthHandler authHandler = new AuthHandler();////        validateHandler.next(loginHandler);//        loginHandler.next(authHandler);////        validateHandler.doHandle(new Member(loginName,loginPass));        Handler.Builder builder = new Handler.Builder();        builder.addHandler(new ValidateHandler())                .addHandler(new LoginHandler())                .addHandler(new AuthHandler());        builder.build().doHandle(new Member(loginName,loginPass));    }}

      责任链模式的优缺点:

      优点:

      • 将请求与处理解耦
      • 请求处理者只需关注自己感兴趣的请求进行处理,对于不感兴趣的请求,直接转发给下一级节点对象。
      • 具备链式传递处理请求功能,请求发送者无需知晓链路结构,只需等待请求处理结果;
      • 链路结构灵活,可以通过改变链路结构动态地新增或删除责任
      • 易于扩展新的请求处理类,符合开闭原则

        缺点:

        • 责任链太长或者处理时间过长,会影响整体性能
        • 如果节点对象存在循环引用时,会造成***循环,导致系统崩溃。

上一篇:主机关机就定住画面关不了

下一篇:腾讯云服务器点播收费吗多少钱(腾讯云服务器点播收费吗多少钱啊)