扩展基类以包含详细信息?

时间:2013-02-27 11:30:12

标签: c# oop solid-principles

我的DAL返回了DTO。例如

public class CustomerDTO
{
    public int CustId {get; set; }
    public int CustType {get; set; }
    .
    . 
    .
    public string GetCustomerTypes{
      get {  if (CustType== 1) 
               return "Special Customer";
             else if(CustType==
}

现在我的课程中有多个属性,这些属性与任何表格都没有关联。只是代表一些属性的代码,例如我可以拥有的CustId(1 ='特殊客户',2 ='违约者'或3 ='新客户')。现在我需要在DTO上显示它们的属性。

我可以将业务逻辑嵌入到SQL语句或我的DTO类中,如上所述。但是,对于各种列,我最终会得到很多条件逻辑。另外,如果我再制作另一个DTO,这个条件逻辑会再次重复。

如何将此逻辑封装在我的班级设计中?避免重复?

4 个答案:

答案 0 :(得分:2)

如果重复某个逻辑,你应该把它放在一个单独的方法中。方法的位置取决于系统的结构,但通常有三个主要选项:

  • 将逻辑放入辅助类
  • 将逻辑放入基类
  • 将逻辑放入扩展方法

第一个选项是最简单的,只需要很少的修改:只需添加一个带静态方法的类,如下所示:

static class DtoHelper {
    public static string GetCustomerType(int type) {
        ... // Custom logic goes here
    }
}

第二种方法灵活性最低,因为它需要你的DTO继承一个公共类:

class WithCustomerType {
    private int custType;
    public string CustomerType {
        get {
            ... // Custom logic goes here
        }
    }
}
public class CustomerDTO : WithCustomerType {
    ...
}

第三个选项更灵活,因为它使用的是接口而不是类型:

interface IWithRawCustomerType {
    int RawCustomerType {get;}
}
static class DtoExtensions {
    public static string GetCustomerType(this IWithRawCustomerType dto) {
        int type = dto.RawCustomerType;
        ...
    }
}
class CustomerDTO : IWithRawCustomerType {
    ...
}

答案 1 :(得分:1)

您可以使该类成为局部,并在分部类中编写额外的逻辑。如果它对所有DTO都是通用的,您可以将额外的逻辑放在基类中,并在为DTO创建的所有部分类中继承它。

对于将类型“转换”为字符串的问题,只需定义Enum CustomerType并在每个值的自定义属性中设置所需的文本。这样,您将拥有的通用逻辑将返回您在每个实体中具有的Type属性的Attribute值。

像这样:Get enum from enum attribute

因此,对于您的示例,我将定义一个枚举:

public enum CustomerType
{
[Tag("SpecialCustomer")]
SpecialCustomer = 1,
...
}

然后在部分类中(如果权限是生成代码)我会将默认成员包装到一个属性中,如下所示:

public string CustomerTypeAsString
{
 get
    { 
        return GetTagValue(CustType);
    }
}

答案 2 :(得分:1)

我建议你把这些值放在数据库中。您可以构建单独的表,如:

CREATE TABLE CustomerTypes (
    ID INT PRIMARY KEY IDENTITY(1, 1),
    Name VARCHAR(50) NOT NULL
)

或者您可以构建一个包含类型代码的表,如:

CREATE TABLE ListTypes (
    ID INT PRIMARY KEY IDENTITY(1, 1),
    Name VARCHAR(50) NOT NULL,
    TypeCode CHAR(2) NOT NULL
)

无论哪种方式,当您从数据库中收集DTO时,请加入这些表并获取该值。因此,如果您构建了一个表,它可能看起来像:

SELECT c.*, ct.Name FROM Customer c
    JOIN CustomerTypes ct ON ct.ID = c.CustType

如果您要使用类型代码更通用的表,它可能如下所示:

SELECT c.*, lt.Name FROM Customer c
    JOIN ListTypes lt ON lt.ID = c.CustType AND lt.TypeCode = '01'

这种方法对你来说效果很好的原因是因为你需要字符串值,但仅用于显示目的,而且你将需要很多类型的东西。此外,您已经在数据库中获取实体,因此让数据库执行此操作。最后,如果您想在组合框中列出这些值并让用户选择它们,您可以从数据库而不是静态绑定该组合框。

但简而言之,这使您的应用程序更容易修改和扩展。

答案 3 :(得分:1)

扩展方法怎么样

 public static  class DerivedValues
 {
     public static void ToCustomerTypes(this CustomerDTO dto)
     {
             if (dto.CustType == 1)
             dto.GetCustomerTypes = "Special Customer";
     }
 }

主要用途

var c1 = new CustomerDTO();
        c1.ToCustomerTypes();