设计模式(1):策略模式原理及实践

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

策略模式的结构组成:

       —抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

       —具体策略角色:包装了相关的算法和行为。

       —环境角色:持有一个策略类的引用,最终给客户端调用

 

原理我相信大家都知道,应该如何应用呢?怎样融合到项目开发中?

使用策略模式可以很容易实现可插拔系统的设计。

策略模式实践场景(1):  普通应用场景,基于普通jar包里面的应用

1.定义抽象策略角色TargetInterface,具体策略角色:教师TeacherImpl和学生StudentImpl,环境角色PolicyManager

/**
 * 抽象策略角色
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:31
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:31
 */
public interface TargetInterface {

    //策略方法
    String read();
}



/**
 * 具体策略角色: 学生
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:32
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:32
 */
public class StudentImpl implements TargetInterface {

    @Override
    public String read() {
        return "学生";
    }
}


/**
 * 具体策略角色:教师
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:33
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:33
 */
public class TeacherImpl implements TargetInterface {

    @Override
    public String read() {
        return "教师";
    }
}


/**
 * 环境角色
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:39
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:39
 */
public class PolicyManager {

    private TargetInterface targetInterface;

    public PolicyManager(TargetInterface targetInterface) {
        this.targetInterface = targetInterface;
    }

    public String read() {

        return targetInterface.read();
    }
}

2.编写测试类

    /**
     * 普通应用场景
     */
    public static void commonTest() {
        TargetInterface studentImpl = new StudentImpl();
        PolicyManager policyManager = new PolicyManager(studentImpl);

        TargetInterface teacherImpl = new TeacherImpl();
        PolicyManager policyManager1 = new PolicyManager(teacherImpl);

        System.out.println("======================" + policyManager.read());
        System.out.println("======================" + policyManager1.read());
    }

结果输出:

==========================学生
==========================教师

策略模式实践场景(2):基于框架的使用,比如某个接口有很多实现(100个),在某个service中需要调用10个不同的实现类,那么就需要注入10个实现类,就会看到好多@Resource(name = "serImpl")的注解。那么代码看起来就很费劲了。

笔者基于上面的类做些改变,融合到框架中。

1.每个具体策略角色添加@Service注解,把对象交给spring框架管理,创建spring框架管理者SpringContextManager,动态获取bean实例

/**
 * 抽象策略角色
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:31
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:31
 */
public interface TargetInterface {

    //策略方法
    String read();
}


/**
 * 具体策略角色: 学生
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:32
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:32
 */
@Service
public class StudentImpl implements TargetInterface {

    @Override
    public String read() {
        return "学生";
    }
}


/**
 * 具体策略角色:教师
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:33
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:33
 */
@Service
public class TeacherImpl implements TargetInterface {

    @Override
    public String read() {
        return "教师";
    }
}

/**
 * 环境角色
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:39
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:39
 */
public class PolicyManager {

    private TargetInterface targetInterface;

    public PolicyManager(TargetInterface targetInterface) {
        this.targetInterface = targetInterface;
    }

    public String read() {

        return targetInterface.read();
    }
}

/**
 * spring框架管理
 *
 * @author: fengyantao
 * @date: 2019/11/14 上午11:39
 * @version: V1.0
 * @review: fengyantao/2019/11/14 上午11:39
 */
@Configuration
@SuppressWarnings("all")
public class SpringContextManager implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext contex) throws BeansException {
        applicationContext = contex;
    }

    public static ApplicationContext getContext() {
        return applicationContext;
    }

    /**
     * 根据类从spring上下文获取bean。
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        Assert.notNull(applicationContext, "SpringContextManager启动失败...");
        return applicationContext.getBean(clazz);
    }

    /**
     * 根据类名从spring上下文获取bean。
     *
     * @param beanId
     * @param <T>
     * @return
     */
    public static <T> T getBean(String beanId) {
        Assert.notNull(applicationContext, "SpringContextManager启动失败...");
        return (T) applicationContext.getBean(beanId);
    }

}

2.编写测试类

    /**
     * 框架应用场景
     */
    public void applicationTest() {
        TargetInterface studentImpl = SpringContextManager.getBean("studentImpl");
        PolicyManager policyManager = new PolicyManager(studentImpl);
        TargetInterface teacherImpl = SpringContextManager.getBean("teacherImpl");
        PolicyManager policyManager1 = new PolicyManager(teacherImpl);

        System.out.println("==========================" + policyManager.read());
        System.out.println("==========================" + policyManager1.read());

    }

结果输出:

==========================学生
==========================教师

 

到此为止就讲完了,如果有问题,欢迎留言或私信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值