设计模式--装饰者模式

现在在做贵州南明的绩效考核系统,遇到这样一个需求:

现在需要做个下了数据列表,里面取考核方案。现在这个考核方案数据集合,有权限限制。现在数据库表结构是这么设计的。

 

有一张考核方案主表,里面描述了考核方案的基本信息,比如考核方案编号,方案名称等等。

还有2张权限控制表,一张是方案机构表,此表描述了机构下的方案集合。一张是方案角色表,描述了方案于角色的关系。

 

现在的权限是,我需要根据登陆者的登陆机构,和他的角色,分别查找方案机构表,和方案角色表,把两张表的方案去重复形成一个方案数据集合。


 这样问题也来了,如果现在系统要扩展,方案的权限增加,比如,要求方案和岗位要挂钩。那我们又当如何。当然,这样的需求,数据库方面,在增加个方案岗位关系表就可以满足需求,关键是,我们程序又当如何去适应这样的变化。

 

按照现在的做法,又得把相关代码拿出来修改,有的甚至要改很多地方。
  对这样的需求,我们先看看用继承是怎么去适应这样的需求:
  现在方案集合只更机构和角色相关联:

public class A
  {

      private int bankcd;//机构
      private String roleid;//角色

      public List getSchemeList()
      {
         //这里面就是实现用 bankcd 和 roleid 去方案的代码

      }


  }

现在需求变化,要求把岗位增加进去,数据库岗位方案表建好了,程序的变化用继承来

public Class B extends A
 {

    private String workid;//增加了岗位

    //overwirte 重写超类方法
    public List getSchemeList()
      {
         List list01=super.getSchemeList();
         
         List list02=......//这里通过使用workid取方案集合
         List listsum......这里listsum合并list01和list02的方案
         
        return  listsum;

      }
 }

以此类推,如果在增加权限,Class C 再继承 B,再重写getSchemeList的方法

这样做的问题再于:
       在这条继承链上,A<--B<--C  顺序是不能随便更改,比如我现在不需要B了,也就是我不要岗位权限了,这就不好去掉,取掉B ,C必然会受到影响。

这里我想到了设计模式的装饰着模式,它很很好的实现上面那种继承功能,但比继承更加灵活。
它的原理好比,在礼物外面,加包装纸,可以加一张,再加一张,顺序也是可以很好变化,去掉一层包装也很容易。
现在的做法:把Class a 的需要被重载的方法getSchemeList()抽像成一个接口,现在被包装着者是Class A,包装者分别有Class B ,和Class C,他们都实现相同的接口。为什么装饰者和被装饰者要继承于同一个基类或实现同一个接口,原因是应为要保证包装者和被包装者的类型要一致。这就好比一颗糖,外面包层糖纸,还是糖的道理是一样的。同过这样方式去实现这样的需求,要易于扩展点。

下面是具体做法:

顶端接口 SchemeInter

public interface SchemeInter {

 /**
  * 更具权限获取方案集合
  * @param map
  * @return
  */
 public List getSchemeList(Map map);
}

具体的被包装组件为SchemeInterImp

public class SchemeInterImp implements SchemeInter {

 public List getSchemeList(Map map) {
  // TODO Auto-generated method stub
  //现在实现的是更具机构和角色取方案集合
  List list=new ArrayList();
  AssMainService service=(AssMainService)SpringUtil.getBean("assMainService");
  list=service.createProgList(map);
  return list;
 }

}

3.包装者抽象类SchemeDecorater

public abstract class SchemeDecorater implements SchemeInter {

//根据权限取方案集合
 public abstract List getSchemeList(Map map);

}

4.具体建了一个更时间类型有关的包装者 SchemeDecoratorTime

public class SchemeDecoratorTime extends SchemeDecorater {
   
 private SchemeInter schemeinter;//每个装饰者都有一个被装饰对象
 
 
 public SchemeDecoratorTime(SchemeInter schemeinter)
 {
  this.schemeinter=schemeinter;
 }
 @Override
 public List getSchemeList(Map map) {
  // TODO Auto-generated method stub
  List list=new ArrayList();
  List suplist=schemeinter.getSchemeList(map);
  
  //合并超类集合和现在加上时间段的数据结合
  list=suplist;
  
  
  return list;
 }

}

5.具体调用代码

//用装饰者模式实现数据的获取
  List list=new ArrayList();
  SchemeInter wrapedobj=new SchemeInterImp();//实例化一个被包装对象
  wrapedobj=new SchemeDecoratorTime(wrapedobj);//形成第一成包装
  //在下面增加其它包装
  wrapedobj=new SchemeDecoratorOther(wrapedobj);//第2成包装

 .......................................
  //
  list=wrapedobj.getSchemeList(map);

 

posted on 2018-04-23 20:29  java熊猫  阅读(42)  评论(0编辑  收藏  举报

导航