阅读内容 

如何使用设计模式来构造系统--(6)

[日期:2008-08-20] 来源:  作者: [字体: ]
     (声明:本系列所用的模式都来自GOF23中,本系列并不是讲23种经典设计模式,而是如何去使用这些模式)
  
  前面我们设计完成了统计部门工资,这样的一个需求,但是在我们设计遍历员工信息的方法是固定不变的,也就是说是硬编码在PersonComposite类中的,由于Composite设计模式相当于一个树或者图的数据结构,那么他的遍历就会出现变化,比如在遍历部门和小组的时候采取不同的方法,以减少遍历的时间,那么如何去解决这个问题呢?
  
  
  
  看看我们的意图:我们需要不同的遍历方式,来遍历Composite中的Person列表集合.
  
  
  
  GOF中的Iterator(遍历器)模式:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。与我们的意图相符,采用!
  
  
  
  我们来看看代码(具体的代码请查看前一篇,这里只列出关于这一模式的代码):
  
  
  
  Person:
  
  
  
  
  
  Code
  public interface IComposite
  {
   double GetShouldpaid();
  }
  
  public class PersonComposite :IComposite
  {
   private ArrayList composite=new ArrayList(); //维护一个Icomposite的列表
  
   public ArrayList Composite
   {
   get{return composite;}
   set { composite = value; }
   }
   public void AddComposite(IComposite com)
   {
   composite.Add(com); //添加一个Icomposite的子类
   }
   public void RemoveComposite(IComposite com)
   {
   composite.Remove(com); //删除一个Icomposite 的子类
   }
   public double GetShouldpaid()
   {
   double x=0;
   for (int i = 0; i < composite.Count; i++) //遍历当前维护的Icomposite的列表
   {
   IComposite com = (IComposite)composite[i];
   x += com.GetShouldpaid(); //递归到当前列表i元素的GetShouldpaid
   }
   return x;
   }
  }
  
  
  
  
  Iterator:
  
  
  
  Code
   public interface Iterator
   {
   IComposite First(); //数据结构的第一个元素
   bool Next(); //当前的下一个元素
   IComposite Current(); //当前元素
   }
  
   public class Listterator : Iterator //具体的Iterator
   {
   private int i=-1; //标记当前位置
   public PersonComposite com; //维护一个数据结构
   public Listterator(PersonComposite agg)
   {
   this.com = (PersonComposite)agg;
   }
   public IComposite First()
   {
   return (IComposite)com.Composite[0];
   }
   public bool Next()
   {
   i++;
   if (i>com.Composite.Count-1)
   {
   i = com.Composite.Count-1;
   return false;
   }
   return true;
   }
   public IComposite Current()
   {
   return (IComposite)com.Composite[i];
   }
   }
  
  
  
  在遍历器中维护了一个PersonComposite,这样的数据结构,你可以自己定义任何的数据结构,让Iterator来维护和遍历,这里没有用到Person这个叶结点,是因为他没有列表不需要去遍历,而PersonComposite的列表中,既可能有Person,也可能有PersonComposite他们都继承自Icomposite,所以Iterator的接口中的方法,都是返回Icomposite类型的。
  
  
  
  客户端代码:
  
  Code
  class Program
   {
   static void Main(string[] args)
   {
   StaffAndSalaryFactory saf = new StaffAndSalaryFactory(); //实例化工厂
   AbstractPerson staff1 = saf.GetPerson(); //创建员工
   staff1.PersonName = "涵舍愚人1";
   staff1.PersonSalary = saf.GetSalary();//创建员工工资
   staff1.PersonSalary.Salaryprize = BadPrize.badPrize;//使用单件初始化员工工资的绩效部分
   //该员工工资为:6000+绩效3000=9000
  
   AbstractPerson staff2 = saf.GetPerson(); //创建员工
   staff2.PersonName = "涵舍愚人2";
   staff2.PersonSalary = saf.GetSalary();//创建员工工资
   staff2.PersonSalary.Salaryprize = GoodPrize.goodPrize;//使用单件初始化员工工资的绩效部分
   //该员工工资为:6000+绩效6000=12000
  
   PersonComposite pc2 = new PersonComposite();
   pc2.AddComposite(staff2);//将Staff2加到部门PC2
   pc2.AddComposite(staff1);//将Staff2加到部门PC2
  
   Listterator ltt = new Listterator(pc2); //初始化遍历器
   while (ltt.Next())
   {
   AbstractPerson com= ltt.Current() as AbstractPerson;
   if (com != null) //如果是具体人员则打印出他的工资
   {
   Console.Write(com.PersonName+"\t"+ com.GetShouldpaid() + "\r\n");
   }
   }
  
   Console.Read();
   }
   }
  
  
  输出结果:
  
  OK,这样我们就可以根据自己的需要而去用任何方式遍历PersonComposite,你也可以让PersonComposite维护一个遍历器,然后在初始化PersonComposite时,给与不同的遍历器,方便类库使用人员的调用,具体的看需求了.  
阅读:
录入:blue1000

推荐 】 【 打印
相关新闻      
本文评论       全部评论
  不好   (无 ,2008-08-25 )
发表评论
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款


点评: 字数
姓名:
Advertisement
内容查询


Advertisement