为了说明问题,我举一简单的例子.hiberate中,班级学生建模块.目前我的做法为:1)班级对象(班级的基本属性,学生的集合)
2)学生对象(学生的基本属性,班级对象)问:
若系统进行了扩展,加入了桌子对象(一个班级中有许多桌子),模型就必须变成:
1)班级对象(班级的基本属性,学生对象集合,桌子对象集合)
2)学生对象(学生的基本属性,班级对象)
3)桌子对象(桌子的基本属性,班级对象)是这样建吗?
若是,那我就觉得这种做法不好了.原因为:
程序员A已写好了"班级与学生"模块程序.当初程序员A建模时的班级对象为(班级的基本属性,学生的集合).代码为:班级 p = new 班级(基本属性,学生集合)因后来扩展了桌子而导致班级对象发生了改变.程序员A就不得不修改他写的程序了.代码必须改成:
班级 p = new 班级(基本属性,学生集合,桌子集合)这样的话,这种设计就不好了,系统扩展了,并不能保证班级与其它对象没有关系,一旦增加一个与班级发生关系的对象,以往写的代码全得改了???大家觉得呢?

解决方案 »

  1.   

    具体程序为:
    1)数据库设计
    班级(班级ID,班级名称)
    学生(学生ID,学生姓名,班级ID)
    桌子(桌子ID,桌子颜色,班级ID)2)对象关系
    班级cls(clsID,clsName,student[],desk[])
    学生student(studentno,studentName,cls)
    桌子desk(deskID,color,cls)偶就是觉得这种对象关系建得不合理,不能保证系统不扩展.一旦扩展班级对象就得变,以往的程序也得变.变的过程为:张三今天的写法为:cls p = new cls(clsid,clsname,student[])增加班级方法(p);===============
    系统扩展了,要加入桌子.班级对象变成了:班级cls(clsID,clsName,student[],desk[])张三不得不写成:
    cls p = new cls(clsid,clsname,student[],desk[])
    增加班级方法(p);
    天呀,要是这样,我情愿死掉....请高手来讲讲.谢谢
      

  2.   

    我提问者,回复:csharp_start 你的意思是指改成:1)班级基类 ClsBase(clsid,clsname) --这里不需要学生集合
    2)班级学生关系类 ClsStudent
    class ClsStudent:ClsBase
    {
    private student[] sarray;public student[] Sarray
    {
    ......
    }
    }当加入班级桌子ClsDesk是class ClsDesk:ClsBase
    {
    private desk[] darray;public desk[] Darray
    {
    ......
    }是这意思吧?
    }
      

  3.   

    我要等人来...人呢?csdn中的人呢?
      

  4.   

    jiangwuren 说的挺好的,
    继承类应满足他的要求了,但我想顺便问一下。不知我想的是不是有问题,我的意思是又增加了椅子对像呢?是不是要继续继承下去。即,当加入班级椅子ClsChair时 class ClsChair:ClsBase 

    private chair[] darray; public chair[] Darray 

    ...... 

    }基类不是应放一些公共的部分属性吗?那学生 和桌子有什么公共的属性可以放在班级的基类中呢?能不能举个例子,因为我感觉 我明白了,但是不透,你能帮我再细举个例子吗?让我再透一下。我好了解到好处,以后就可以发扬光大了。也是一个模式新学者。
      

  5.   

    顺便 问一下jiangwuren ,private chair[] darray;  
     
    是做什么用的呢?
      

  6.   

    csdn中的星星们呢?请进来看下呀..............
      

  7.   

    如果桌子不是必须的构造参数,可否用以下的构造函数重载方法处理呢?public cls(clsid,clsname,student[]) 
    {
    m_clsid = clsid;
    m_clsname = clsname;
    m_student  =student;
    ...
    }public cls(clsid,clsname,student[],desk[]) 
      this(clsid,clsname,student)
    {
    m_desk = desk;
    ....
    }
      

  8.   


    using System;
    using System.Collections.Generic;namespace Mynamespace
    {
      public abstract class Baseclass
      {
         public abstract void PrintInfo();
      }
      public class Newclass : Baseclass
      {
        private string _Classname;
     public string Classname
     {
       get { return _Classname;}
       set { this._Classname=value;}
     }
     public override void PrintInfo()
         {
       Console.WriteLine("New Class is :" + _Classname);
         }  
      }
      public class Student
      {
        private string _Studentname;
    public string Studentname
    {
       get { return _Studentname;}
       set { this._Studentname=value;}
    }
      }
      public class Desk
      {
        private string _Deskname;
    public string Deskname
    {
       get { return _Deskname;}
       set { this._Deskname=value;}
    }
      }
      public abstract class ClassWrapper : Baseclass
      {
         private Baseclass _Baseclass;
     public ClassWrapper(Baseclass Bc)
     {
        this._Baseclass = Bc;
     }
     public override void PrintInfo()
         {
       _Baseclass.PrintInfo();
     }
      }
      public class StudentClassWrapper : ClassWrapper
      {
     private List<Student> _StudentCollection;
     public StudentClassWrapper(Baseclass Bc):base(Bc)
     {
    _StudentCollection = new List<Student>();
     }
     public void Add(Student sd)
     {
       _StudentCollection.Add(sd);
         }
     public void Remove(Student sd)
     {
       _StudentCollection.Remove(sd);
     }
     public List<Student> Studentlist
     {
       get { return _StudentCollection;}
     }  
     public override void PrintInfo()
         {
        foreach(Student sd in _StudentCollection)
       Console.WriteLine("Student Name is :"+sd.Studentname);
    base.PrintInfo();
     }
      }
      public class DeskClassWrapper : ClassWrapper
      {
         private List<Desk> _DeskCollection;
     public DeskClassWrapper(Baseclass Bc):base(Bc)
     {
    _DeskCollection = new List<Desk>();
     }
     public void Add(Desk dk)
     {
       _DeskCollection.Add(dk);
         }
     public void Remove(Desk dk)
     {
       _DeskCollection.Remove(dk);
     }
     public List<Desk> Desklist
     {
       get { return _DeskCollection;}
     }  
     public override void PrintInfo()
         { 
        foreach(Desk dk in _DeskCollection)
       Console.WriteLine("Desk Name is :"+dk.Deskname);
    base.PrintInfo();
     }
      }
      public class myClass
      {
         public static void Main()
     {
        Newclass bc = new Newclass();
    bc.Classname = "一年级三班";

    Student sd = new Student();
    sd.Studentname = "小明";
    StudentClassWrapper scw = new StudentClassWrapper(bc);
    scw.Add(sd);
    scw.PrintInfo();

    Desk dk = new Desk();
    dk.Deskname = "第一张";
    DeskClassWrapper dcw = new DeskClassWrapper(scw);
    dcw.Add(dk);
    dcw.PrintInfo();
     }
      }
    }这个例子是装饰模式
    在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?这就是Decorator模式。
    动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
      

  9.   

    这就是个最简单的实体类型, 不要想的太复杂
    构造函数参数只需要id和name 2个参数就可以了, 难道要把所有的属性都当作构造函数的参数?
    学生集合和桌子集合提供访问器方法就可以了.