课程咨询 :186 8716 1620      qq:2066486918

昆明Java培训 > 达内新闻 > java培训:使用多个策略
  • java培训:使用多个策略

    发布:昆明Java培训      来源:达内新闻      时间:2016-10-19

  • 昆明Java培训班的老师今天给大家讲怎么使用多个策略。

    假设现在我们的情景变化了,除了根据工作年限计算年假天数之外,还要根据在当前公司的工作年限计算年假天数,什么意思呢?比如你本来工作了5年,根据国家规定你有5天年假,但是你在当前这家公司只工作了1年,当 这家公司规定工作满2年就有一天额外的年假,5年到10年就有额外的5天年假,这时候怎么搞呢?我们上面的代码只能满足使用一种策略算法,无法满足同时使用两种策略算法;

    同样参考上面说的,完成了使用两种策略的代码,但是其中使用了代理模式,这里昆明Java培训班的老师就先把我的代码贴上,:

    三个注解

    这里需要三个注解来实现上述的功能,其中一个是上面已经完成,另外两个如下所示:

    国家规定的年假策略使用的注解

    @Target(ElementType.TYPE)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface NationalRange {

    ValidateRange value() default @ValidateRange;

    }

    公司年假策略使用的注解

    @Target(ElementType.TYPE)

    @Retention(RetentionPolicy.RUNTIME)

    public @interface CompanyRange {

    ValidateRange value() default @ValidateRange;

    }

    给策略类添加注解

    国家规定的年假的策略类和公司的年假策略类昆明Java培训班的老师各给出一个例子,其他类似:

    @NationalRange(@ValidateRange(min=1,max=10))

    public class FiveDays implements VacationDays{

    @Override

    public int getVacationDays() {

    System.out.println("国家规定:工作1到10年,年假5天");

    return 5;

    }

    }

    @CompanyRange(@ValidateRange(min=10))

    public class CompanyTenDays implements VacationDays{

    @Override

    public int getVacationDays() {

    System.out.println("公司:在当前公司10年以上,10天年假");

    return 10;

    }

    }

    动态代理类

    public class DaysProxy implements InvocationHandler{

    private List<Class<? extends VacationDays>> list;

    public DaysProxy(List<Class<? extends VacationDays>> list){

    super();

    this.list = list;

    }

    @Override

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    int result = 0;

    if(method.getName().equals("getVacationDays")){

    for(Class<? extends VacationDays> cla : list){

    result += (int)method.invoke(cla.newInstance(), args);

    }

    System.out.println("年假总天数"+result);

    return result;

    }

    return null;

    }

    public static VacationDays getProxy(List<Class<? extends VacationDays>> list){

    return (VacationDays) Proxy.newProxyInstance(DaysProxy.class.getClassLoader(), new Class<?>[]{VacationDays.class}, new DaysProxy(list));

    }

    }

    简单工程类

    /*根据注解生成实例*/

    public VacationDays create(int workYears,int owCompanyYears){

    //在策略列表查找策略

    List<Class<? extends VacationDays>> list = new ArrayList<Class<? extends VacationDays>>();

    for(Class<? extends VacationDays> cla : daysList){

    Annotation range = handleAnnotation(cla);

    if(range instanceof NationalRange){

    NationalRange nrange = (NationalRange)range;

    if(workYears >= range.value().min() && workYears < nrange.value().max()){

    list.add(cla);

    }

    }else if(range instanceof CompanyRange){

    CompanyRange crange = (CompanyRange)range;

    if(nowCompanyYears >= crange.value().min() && nowCompanyYears < crange.value().max()){

    list.add(cla);

    }

    }

    }  

    return DaysProxy.getProxy(list);

    }

    //处理注解,我们传入一个策略类,返回它的注解

    private Annotation handleAnnotation(Class<? extends VacationDays> clazz){

    Annotation[] annotations = clazz.getDeclaredAnnotations();

    if (annotations == null || annotations.length == 0) {

    return null;

    }

    for (int i = 0; i < annotations.length; i++) {

    if (annotations[i] instanceof NationalRange || annotations[i] instanceof CompanyRange) {

    return annotations[i];

    }

    }

    return null;

    }

    简单工厂类发生变化的只有两个地方,一个是要传入在当前公司工作的年限,第二就是需要返回策略类的注解时只要满足上面生成的两个注解其一就可以。

    此时Custom类变化如下:

    public void checkVocationDays(int workYears,int nowCompanyYears){

    //两种策略同时使用

    days = DoubleStrategyFactory.getInstance().create(workYears, nowCompanyYears);

    }

    客户端调用:

    Custom c= new Custom();

    c.checkVocationDays(25,15);

    c.calcateDays();

    优/缺点

    优点

    策略类之间可以自由切换,由于策略类实现自同一个抽象策略类,因此可以进行互换;容易扩展,添加新的策略时基本不需要修改原有代码,特别在消除判断语句之后就更不需要修改大部分代码,只需要在对应的包中添加上类 同时给类加上对应的注解即可;部分情况下避免使用多重条件判断;

    缺点

    如果策略很多,那么就需要维护很多的策略类,为开发带来额外的开销;必须对客户端爆露所有的策略,因为使用哪种策略是由客户端决定的,如果客户端对于各个策略不了解,那么是无法正确调用的;

    适用场景

    多个类只区别在表现行为不同,可以在运行时动态选择具体要执行的行为;需要在不同的情况下适用不同的策略,或者说同样的事情还有其他的实现方式,以后还会添加新的实现方式;对客户端隐藏算法的具体实现过程,将算 的具体实现和责任独立开来;

    昆明Java培训班的老师的总结

    单纯的策略模式在我上面的进阶标题之前就已经完成,单纯的策略模式是相对简单的,只需要一系列的策略实现一个相同的抽象,并且在上下文类中持有抽象策略类以供调用即可,但是对于策略类的完善和补充确实是比较复杂

    推荐文章

上一篇:策略模式中怎么注解消除判断语句

下一篇:IO流之文件的递归

最新开班日期  |  更多

Java--零基础全日制班

Java--零基础全日制班

开班日期:11/30

Java--零基础业余班

Java--零基础业余班

开班日期:11/30

Java--周末提升班

Java--周末提升班

开班日期:11/30

Java--零基础周末班

Java--零基础周末班

开班日期:11/30

  • 网址:http://km .java.tedu.cn      地址:昆明市官渡区春城路62号证券大厦附楼6楼
  • 课程培训电话:186 8716 1620      qq:2066486918    全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56