2009-11-19 126 views
2

我在尝试使我的体系结构具有灵活性时面临类解决问题。为简单起见,考虑下面的例子:C#OOP体系结构问题

我有四个层次:用户界面,BL,普通和DAL

我有我的BL层基类,定义如下:

public class User 
    { 
     private UserDTO _d; 
     public User() 
     { 
      _d = new UserDTO(); 
     } 
     public User(UserDTO d) 
     { 
      _d = new UserDTO(d); 
     } 
     public UserDTO D 
     { 
      get { return _d; } 
      set { _d = value; } 
     } 

     //static method (I cannot make it non-static due to some reasons) 
     public static User GetUser() 
     { 
      User user = new User(Provider.DAL.GetUser()); 
      return user;    
     } 
    } 

该DTO定义为:

public class UserDTO 
    { 
     public int ID; 
     public UserDTO() 
     { 
     } 

     public UserDTO(UserDTO source) 
     { 
      ID = source.ID; 
     } 
    } 

我DAL被定义为(它返回一个DTO不是一个业务对象):

public static UserDTO GetUser() 
     { 
      UserDTO dto = new UserDTO(); 
      dto.ID = 99; 
      return dto; 
     } 

现在,我想“扩展”我的代码,这样我可以在我的用户表中有一个字段:名称。所以,我创建一个派生DTO类为:

public class MyUserDTO : UserDTO 
    { 
    public string Name; 
    public MyUserDTO() 
    { 
    } 

    public MyUserDTO(MyUserDTO source) 
    { 
     Name = source.Name; //new field 
     base.ID = source.ID; 
    } 
} 

然后,我创建了一个派生用户类为:

public class MyUser : User 
    { 
     public MyUser() 
     { 
      this.D = new MyUserDTO(); 
     } 
    } 

我创建这个方法我自己的自定义DAL提供商:

public static UserDTO GetUser() 
     { 
      UserDTO dto = new MyUserDTO(); 
      dto.ID = 99; 
      ((MyUserDTO)dto).Name = "New Provider Name"; 
      return dto; 
     } 

现在,当我访问我的BL中的MyUserDTO对象时,它失去了分辨率:

User.GetUser(DAL.Provider.GetUs呃())

在UI中,我没有得到MyUserDTO中的属性。

即使在我调用静态User.GetUser()方法(这又会调用我的自定义提供程序返回MyUserDTO对象)之后,是否有方法可以帮助我获取UI层中的这些属性?

感谢,

回答

5

你不从继承类中添加新的数据,只有当你的新类是要延长你的旧类的行为继承。

给你的UserDTO一个Name-Value集合来存放它的数据并填充它。那么你不会有问题。

1

您没有得到派生的行为,因为用户类中的静态方法不能被MyUser类重写。

你应该删除静态方法(我知道你已经表示你不能),但你真的应该。

尝试提取用户的创建另一个对象(工厂,仓库,...)

0

从我看到它看起来像User.GetUser()将返回用户对象,而不是MyUserDTO对象,这就是为什么你没有得到这些额外的领域。 DAL层需要遵守所写的合同。有几种方法可以解决这个问题,尽管有些方法比其他方法更“正确”。

您可以将您从User.GetUser中获取的对象转换为适当的对象,然后该对象将允许您访问铸造对象的字段(假定该对象可以转换为该类型)。我真的不喜欢从设计的角度来看这个解决方案,但它的工作:

MyDTOUser myDtoUser = User.GetUser() as MyDTOUser; 

其他人已经张贴的方式其他一些例子解决此所以我就不再重复那些在这里。

1

正如其他人所说的,问题在于静态方法。

我也建议使用泛型或依赖注入来清理你的并行对象层次结构。你不希望重复。

而是具有一组几乎相同的“用户”和“MYUSER”类,即具有相同的层次,只是做一些这样的用户,并插入所需的UserDTO类型。

如果您重构并删除对象层次结构重复,可能会更容易发现解决静态GetUser()问题的良好解决方案。