现在用COM+开发一个项目,有用户管理这么一个功能,主要可以增加,修改,删除用户,还可以设置用户所属的角色。假设用户管理中会用到用户类(TUserInfo),角色类(TRole)等。问题如下:1.在设计时,应该是把整个用户管理做为一个组件显示在组件下(组件服务管理控制面板里的),还是把用户管理中所用到的几个类分别做为组件来显示。如果把用户管理做为一个组件的话,那它提供的接口可能就应该是用户管理功能里面所用到的几个类的方法的一个并集,如包含(TUser.adduser,TUser.deleteUser, TRole.GetRole等),这样的好处是可以减少客户端(显示层)维护的对象,但会使接口的方法过多;但如果把用户管理中用到的类分别作为组件的话,那客户端就可以直接与TUser,TRole来交互,这样不必再生成一个中间类来交互。不知道这两种设计应该用哪种好,还是在做分布式开发设计中有其他好的设计方法,请各位发表自己的看法。
代码样例:
TUser = class(..., IUser)
  AddUser;
  DeleteUser;
  GetUser;
end;TRole = class(..., IRole)
  GetRoleList;
  ...
end;IUserManage = class
  AddUser;
  DeleteUser;
  GetUser;
  GetRoleList;
  ...
  这里可能有很多方法,是以上两个类的一个并集,
  在实现时, IUserManage 的实现类实际上调用TUser, TRole中的方法 
end;

解决方案 »

  1.   

    从你的设计想法来说,都有可取之处, 比如说IUserManage其实体现了一种模式思想(FACADE).
    但就你从2种设计方式的比较而言(不以哪种绝对正确来定论),我觉得应该遵循一种设计原则:
    接口隔离原则。
      

  2.   

    要是我的话,会选择第二种方案IUserManage = class。你的设计目标是要完成一个“用户管理”的主题,它可能是由TUser和TRole等配合完成的,而单独的TUser和TRole并不能完成你的设计目标。第一种方案,你需要在客户端申明和建立两个接口对象;第二种方案只需要建立一个。第二种方案更灵活。因为TUser和TRole的属性和方法并没有暴露给用户,只要IUserManage不变,里面的TUser和TRole可以随意改动,客户端不需要重编译。
      

  3.   

    另外请注意,一定要把精力集中在interface的设计上,实现是次要的。
      

  4.   

    呵呵
    //TUser和TRole等配合完成的, 而单独的TUser和TRole并不能完成你的设计目标。对的,但是配合完成不等于拉郎配。有很多术语能够来表达这种配合关系如Composition, Association, Aggregation等等。当然,设计是一项很复杂的工程,这里只是就事论事而已。
      

  5.   

    我贴一段我的交付系统中设计的User、Role的Interface.大概表达相互关系type
      IUser = interface(IVisited)
      ['{81E15358-2569-4712-97D7-C69EC18E6628}']
        function GetUserID: string;
        procedure SetUserID(const Value: string);
        function GetUserName: string;
        procedure SetUserName(const Value: string);
        function GetUserPassword: string;
        function GetRoleList: IRoleListModel;
        procedure SetUserPassword(const Value: string);
        property UserID: string read GetUserID write SetUserID;
        property UserName: string read GetUserName write SetUserName;
        property UserPassword: string read GetUserPassword write SetUserPassword;
        property RoleList: IRoleListModel read GetRoleList;
      end;
      

  6.   

    TO:老冯
    你说要尽量遵循接口隔离原则,这个是对的,我觉得如果用一个IUserManager接口的话,这样好象就违背了接口隔离原则
      

  7.   

    本身系统设计就是在矛盾中建立起来的,没有绝对的好方案。因为一切Principle都等于Perfect.
    任何设计都没有绝对完美的。所以一定要理论结合实际,顺其自然。
      

  8.   

    to: ddqqyy
    第二种方案更灵活。因为TUser和TRole的属性和方法并没有暴露给用户,只要IUserManage不变,里面的TUser和TRole可以随意改动,客户端不需要重编译。用IUserManage是可以保特低耦合,但觉得违背了接口隔离原则。
      

  9.   

    在IUserManager不是十分庞大,也便于维护的情况下,就这样设计也没有什么不可以的。
      

  10.   

    老冯,对于你说的几种配合来完成的方案,如关联,聚合等,我倒觉得象这种一个功能模块的功能,应该单独提出一个类来协调各个类的操作,而不应该为了目的,而把一个类关联到另一个类上。如此例:不应该把TRole关联到TUser上来完成,而应该单独用一个接口或类来协调