1

我有一个这样的客户层次结构:

abstract class Customer {
    public virtual string Name { get; set; }
}

class HighValueCustomer : Customer {
    public virtual int MaxSpending { get; set; }
} 

class SpecialCustomer : Customer {
    public virtual string Award { get; set; }
}

当我检索客户时,我想在 Web 表单上显示要编辑/修改的属性。目前,我使用 if 语句来查找子客户类型并显示专门的属性。是否有设计模式(访问者?)或更好的方法,以便我可以避免表示层中的“if”语句?你怎么做呢?

更多信息:这是一个带有 nHibernate 后端的 asp.net 网站。每个客户类型在页面上都有自己的用户控件,我想根据客户类型自动加载。

4

4 回答 4

2

您可以使用反射来获取特定于子类(实例)的属性列表吗?(不易出错。)

如果没有,请创建一个返回特殊属性的(虚拟)方法。(更容易出错!)

以后者为例:

abstract class Customer {
    public virtual string Name { get; set; }

    public virtual IDictionary<string, object> GetProperties()
    {
        var ret = new Dictionary<string, object>();
        ret["Name"] = Name;
        return ret;
    }
}

class HighValueCustomer : Customer {
    public virtual int MaxSpending { get; set; }

    public override IDictionary<string, object> GetProperties()
    {
        var ret = base.GetProperties();
        ret["Max spending"] = MaxSpending;
        return ret;
    }
} 

class SpecialCustomer : Customer {
    public virtual string Award { get; set; }

    public override IDictionary<string, object> GetProperties()
    {
        var ret = base.GetProperties();
        ret["Award"] = Award;
        return ret;
    }
}

无论如何,您可能想fieldset在您的网页上创建部分(s?),所以if会在那里发挥作用,使这种额外的编码有点烦人和无用。

于 2009-03-12T00:58:28.237 回答
2

我认为一个更干净的组织应该是具有显示控件或格式的并行层次结构。也许使用抽象工厂模式之类的东西同时创建 Customer 和 CustomerForm 的实例。显示返回的 CustomerForm 实例,它会知道额外的属性以及如何显示和编辑它们。

于 2009-03-12T03:53:30.327 回答
0

新的:

interface CustomerEdit
{
    void Display();
}

编辑:

abstract class Customer {
    protected CustomerEdit customerEdit; // customers have an object which allows for edit

    public virtual string Name { get; set; }
    public void Display() { customerEdit.Display(); } // allow the CustomerEdit implementor to display the UI elements
}

// Set customerEdit in constructor, tie with "this"
class HighValueCustomer : Customer {
    public virtual int MaxSpending { get; set; }
} 

// Set customerEdit in constructor, tie with "this"
class SpecialCustomer : Customer {
    public virtual string Award { get; set; }
}

用法:

Customer whichCouldItBe = GetSomeCustomer();
whichCouldItBe.Display(); // shows UI depeneding on the concrete type
于 2009-03-12T09:08:23.690 回答
0

你有没有尝试过这样的事情:

public class Customer<T>
    where T : Customer<T>
{
    private T subClass;
    public IDictionary<string, object> GetProperties()
    {
        return subClass.GetProperties();
    }
}

具有以下子类:

public class FinancialCustomer : Customer<FinancialCustomer>
{
}

这不在我的脑海中,所以可能行不通。我在 CSLA.NET 中看到过这种类型的代码。这是名为BusinessBase.cs的 CSLA.NET 类的链接,它与我上面给出的定义相似。

于 2009-03-12T01:29:08.943 回答