2009-06-10 73 views
2

我正在爲當前項目開發一個大型結賬應用程序。 根據用戶的管理員級別,結帳方式以及檢出的項目類型,此結帳有很多情況,因此通過一組上下文類從.aspx頁面抽取該進程。決定需要哪個子類的最佳方法

這些類從一個類的所有子類,CheckoutContext和要使用的類的類型通過枚舉來標記。

是否有類似的typedef我可以用它來選擇要使用的子類的東西,或者我應該只是有一個返回相關類,像這樣的方法:

CheckoutContext chooseSubclass(CheckoutCase c) 
{ 
CheckoutContext output; 
switch (c): 
{ 
    case CheckoutCase.SingleItemNew: 
    output = new SingleItemNew; 
    break; 
    case . . . 
    return output; 
} 
}

+1

你是否需要這種動態?我的意思是,您多長時間添加一個新的子類,是否需要在不重新編譯應用程序的情況下進行配置?你有多個開發者創建這些子類嗎?如果您正在處理這些類型的多個需求,則可能需要更強大的解決方案。如果沒有,然後堅持開關。 – Josh 2009-06-10 15:32:08

+0

整個過程非常複雜,無法逐一處理,我們每個頁面只需要15個方法來處理哪些字段可用。因此,我們正在將這個過程分成幾類。以後會有更多的可能性,所以我想要一個解決方案,只需要額外的努力就可以添加一個結帳過程。 – 2009-06-10 15:47:18

回答

1

If there are a large number of cases, I would create a Dictionary<CheckoutCase, Type>與設定的填充它一次所有CheckoutCase值和相應的CheckoutContext類型。然後你可以使用Activator.CreateInstance來返回適當的類型,而不是一個巨大的switch語句。

4

What you're implementing is a Factory Pattern . This is a standard practice, though it typically means writing a lot of repetitive code (much like your switch statement, which is often how they're implemented). You could do all sorts of fancy things like dynamic instantiation via reflection, but don't play with fire. Just stick with switch statement and you'll be fine.

0

You could implement this with a custom attribute and a factory method. Make all you Sub Classes implement a CustomAttribute say CheckOutCaseScenarioAttribute that takes the CheckOutCase Enum value.

Within your factory method, look for types that have this Enum Value set and create the object. This will avoid your switch case. This will work if you dont have any other initialization logic within your factory method.

0

This is called a Factory Design Pattern. I would create a static method that returns the needed class. A good practice here is to implement an Interface and return the interface.

interface ICheckoutItem 
{ 
    void CheckOut(); 
} 

Have your items implement the interface. Then in your factory method return the interface of each item.

ICheckoutItem chooseSubclass(CheckoutCase c) 
{ 
ICheckoutItem output; 
    switch (c): 
    { 
     case CheckoutCase.SingleItemNew: 
     output = new SingleItemNew; 
     break; 
     case . . . 
    return output; 
    } 
} 
+0

有什麼優勢可以返回接口而不是基類?如果沒有優勢,那麼這個答案與當前的解決方案相同。 – 2009-06-10 15:38:31

0

您可以創建具有一個屬性的屬性,它是CheckoutContext類型:

public class CheckoutContextAttribute : Attribute 
{ 
    public Type CheckoutType{get;set;} 
} 

然後,在你的枚舉,你可以把正確的屬性上的正確枚舉類型:

public enum CheckoutCase 
{ 
    [CheckoutContext(CheckoutType=typeof(SingleItemNew)] 
    SingleItemNew, 
    ... 
    ... 
} 

而且,在您需要發送回您使用反射正確的上下文類型,做一些像這樣的方法:

public CheckoutContext GetContext(CheckoutCase c) 
{ 
    FieldInfo field = c.GetType().GetField(c.ToString()); 
    object[] attribs = field.GetCustomAttributes(typeof(CheckoutContextAttribute),false); 
    CheckountContext result = null; 
    if(attribs.Length > 0) 
    { 
     CheckoutContextAttribute attrib = attribs[0] as CheckoutContextAttribute; 
     Type type = attrib.CheckoutType; 
     result = Activator.CreateInstance(type) as CheckountContext; 
    } 

    return result; 
} 

這應該可以做到。只需添加一些空/錯誤檢查以確保安全。