设计模式演化之策略模式

定义

针对一组算法,把他们封装到共同的接口类中,从而使得它们可以达到相互替换的目的。

演化

1.实现一个学籍管理系统的主页,可以允许老师和学生登录。两者能看到主页页面相似,但也存在着一些差别。在这种情况下,如果单独为两者各创建一个主页就会显得浪费了。因此我们一般会在主页里边通过身份判断来执行有差异的功能。如加载页面控件:

public class MainPager {
    
    public static final int TYPE_STUDENT = 0;
    public static final int TYPE_TEACHER = 1;
    private int type;
    
    public void initView() {
        if (type == TYPE_STUDENT) {
            // 学生页面展示逻辑
        } else {
            // 教师页面展示逻辑
        }
    }
}

这段代码不多,也能很清晰的展示出不同身份之间的差异

2.增加更多的身份,如班主任,校长之类的。现在这个页面的判断逻辑已经比较复杂了。

public class MainPager {

    public static final int TYPE_STUDENT = 0;
    public static final int TYPE_TEACHER = 1;
    public static final int TYPE_HEADER_TEACHER = 2;
    public static final int TYPE_SCHOOL_MASTER = 3;

    private int type;

    public void initView() {
        switch (type) {
            case TYPE_STUDENT:
                // 学生页面展示逻辑
                break;
            case TYPE_TEACHER:
                // 教师页面展示逻辑
                break;
            case TYPE_HEADER_TEACHER:
                // 班主任页面展示逻辑
                break;
            case TYPE_SCHOOL_MASTER:
                // 校长页面展示逻辑
                break;
            default:
                break;
        }
    }

}

这时initView()方法的内容就过多了,阅读性变差了。很难找出每种身份对应的处理逻辑。然后再给主页增加功能。如增加数据处理initData(),增加校验帐号的逻辑checkAccount()。你会发现每个方法里都充满了switch语句。这些方法动辄就是上百行的执行逻辑,想要找到每种身份的的执行逻辑就变得相当复杂。

3.有没有办法减少判断呢?我们可以把不同身份的执行逻辑分类。在页面初始化的时候根据身份选则其中一个,之后就可以省去这部分的流程了。
(1) 先定义需要需要区别执行的方法接口

public interface Strategy {
    void initView();
    void initData();
    void initEvent();
    void checkAccount();
}

(2) 定义各个身份下的具体实现,这里仅以学生为例

public class StudentStrategy implements Strategy{
    @Override
    public void initView() {
        // 学生页面展示逻辑
    }

    @Override
    public void initData() {
        // 学生数据处理逻辑
    }

    @Override
    public void initEvent() {
        // 学生事件处理逻辑
    }

    @Override
    public void checkAccount() {
        // 学生帐号校验逻辑
    }
}

(3) 主页初始化时根据当前身份,初始化对应的Strategy。然后后续的所有逻辑都交给该Strategy处理。

public class MainPager {

    public static final int TYPE_STUDENT = 0;
    public static final int TYPE_TEACHER = 1;
    public static final int TYPE_HEADER_TEACHER = 2;
    public static final int TYPE_SCHOOL_MASTER = 3;

    private int type;
    private Strategy mStrategy;

    public void initStrategy() {
        switch (type) {
            case TYPE_STUDENT:
                mStrategy = new StudentStrategy();
                break;
            case TYPE_TEACHER:
                mStrategy = new TeacherStrategy();
                break;
            case TYPE_HEADER_TEACHER:
                mStrategy = new HeaderStrategy();
                break;
            case TYPE_SCHOOL_MASTER:
                mStrategy = new MasterStrategy();
                break;
            default:
                mStrategy = new StudentStrategy();
                break;
        }
    }

    private void initView() {
        mStrategy.initView();
    }

    private void initData() {
        mStrategy.initData();
    }

    private void initEvent() {
        mStrategy.initEvent();
    }

    private void checkAccount() {
        mStrategy.checkAccount();
    }
}

此时,各种身份下的处理逻辑各自分类,可读性大大加强。当增加新的身份时,只需要新增对应Strategy实现类即可。同时主页中的处理逻辑也得到了简化。

至此一个策略模式就已经完成了。

优化

1.在上述策略模式中,我们定义的Strategy实现类,是作为MainPager的辅助类出现的,在使用过程中,不可避免的要使用MainPager中的参数。为了方便在Strategy中使用这些参数,我们可以以内部的形式来定义各个实现类。

public class MainPager {

    public static final int TYPE_STUDENT = 0;
    public static final int TYPE_TEACHER = 1;
    public static final int TYPE_HEADER_TEACHER = 2;
    public static final int TYPE_SCHOOL_MASTER = 3;

    private int type;
    private Strategy mStrategy;

    public void initStrategy() {
        switch (type) {
            case TYPE_STUDENT:
                mStrategy = new StudentStrategy();
                break;
            case TYPE_TEACHER:
                mStrategy = new TeacherStrategy();
                break;
            case TYPE_HEADER_TEACHER:
                mStrategy = new HeaderStrategy();
                break;
            case TYPE_SCHOOL_MASTER:
                mStrategy = new MasterStrategy();
                break;
            default:
                mStrategy = new StudentStrategy();
                break;
        }
    }

    private void initView() {
        mStrategy.initView();
    }

    private void initData() {
        mStrategy.initData();
    }

    private void initEvent() {
        mStrategy.initEvent();
    }

    private void checkAccount() {
        mStrategy.checkAccount();
    }

    public class StudentStrategy implements Strategy{
        @Override
        public void initView() {
            // 学生页面展示逻辑
        }

        @Override
        public void initData() {
            // 学生数据处理逻辑
        }

        @Override
        public void initEvent() {
            // 学生事件处理逻辑
        }

        @Override
        public void checkAccount() {
            // 学生帐号校验逻辑
        }
    }

    public interface Strategy {
        void initView();
        void initData();
        void initEvent();
        void checkAccount();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值