2011-08-21 31 views
2

这里的策略里面向下转换是我的问题域,在金融业:想要避免传递到复合

 
Asset 
========== 
Asset parent 
assetID 
+ compareTo(Asset anotherAsset) 

Portfolio : Asset 
----------------- 
name 
risk limit 
List stocks 
+ compareTo(Asset anotherAsset) 
+ composite.CompareTo(Portfolio, ComparisonRules). 

Stock : Asset 
------- 
market 
amount 
company 
+ compareTo(Asset anotherAsset) 

AnotherStock : Stock 
-------------------- 
someOtherProperty 
+ compareTo(Asset anotherAsset) 

我已经应用了复合模式* 组合内结构* 股票 * S * S。我想要一个自定义此复合的compareTo方法的干净方式。也就是说,AnotherStock将永远与另一个AnotherStock,股票与股票进行比较。这看起来像我的战略模式。

我想这样做以下(伪代码)

 
differences = composite.CompareTo(anotherComposite, ComparisonRules). 

composite.CompareTo would be something like : 

ComparisonRules.Compare(this.Stocks[currentAssetID], otherComposite[currentAssetID]) 

ComparisonRules.Compare(资产A,资产B)会做这样的事情丑陋:

 
if(a is Stock and b is Stock) : convert to stock and do stock-based comparison 
else if (a is AnotherStock and b is AnotherSTock): convert to AnotherStock 

是否有以这种方式编写ComparisonRules的方法,我不需要downcast,但仍然提供自定义的ComparisonRules对象?

+0

你的问题并不完全清楚;什么是'composite.CompareTo'?假设你在问题开始时提供了一个类图(类),命名'composite“。CompareTo'无效。另外“定制这个组合的'compareTo'方法并不完全清楚;你的意思是你希望能够提供一个规则列表,并且每条规则都必须处理'AnotherStock','Stock'等。 –

+0

>你的意思是你希望能够提供一个规则列表,并且每条规则必须处理另一个股票,股票,是: –

+0

比较规则是否对两只股票进行操作(即比较一只股票与另一只股票)还是对两个股票清单(比较一个清单到另一个清单)? –

回答

1

从规则的角度来看,它听起来像你需要的是泛型。如果定义这些方针的东西:

public class ComparisonRule<TStock> where TStock : Stock 
{ 
    public int Compare(TStock lValue, TStock rValue) 
    { 
     ... 
    } 
} 

这将保证只有类型或低于TStock将被接受。例如,如果我有一个ComparisonRule<AnotherStock>,则只能传入AnotherStock或以下的类型。但是,如果您希望能够定义可比较Stock而不是AnotherStock的规则,则可能需要重新考虑类型层次结构。你应该考虑有一个共同的祖先,但具体的种类应该在不同的继承树中。

换句话说,你有这样的:

   Stock 
       | 
    -------------------------- 
    |       | 
OneStock    AnotherStock 

这将允许您定义的规则,可以比较任意StockComparisonRule<Stock>,或者一个规则只能比较OneStockComparisonRule<OneStock>

但是,这并不能帮助您理清如何知道哪些对象要传递给更高级别的哪些规则。对于这一点,你需要能够定义的ComparisonRule了一个不太确切的版本,我们可以做到这一点的接口:

public interface IComparisonRule 
{ 
    bool CanCompare(Stock lValue, Stock rValue); 
    int Compare(Stock lValue, Stock rValue); 
} 

public abstract class ComparisonRule<TStock> : IComparisonRule where TStock : Stock 
{ 
    bool IComparisonRule.CanCompare(Stock lValue, Stock rValue) 
    { 
     return lValue is TStock && rValue is TStock; 
    } 

    int IComparisonRule.Compare(Stock lValue, Stock rValue) 
    { 
     return Compare((TStock)lValue, (TStock)rValue); 
    } 

    public abstract int Compare(TStock lValue, TStock rValue); 
} 

现在,严格的说,你的问题问如何做到这一点没有向下转换,这(严格来说)是不可能的。但是,这样可以避免您在每次实施时都这样做。例如,一个简单的规则来比较两个AnotherStock情况将是:

public class MyRule : ComparisonRule<AnotherStock> 
{ 
    public override int Compare(AnotherStock lValue, AnotherStock rValue) 
    { 
     return lValue.someOtherProperty.CompareTo(rValue.someOtherProperty); 
    } 
} 

在较高的水平(即内Portfolio),你可以简单地坚持到IComparisonRule为您的规则清单,然后你可以调用CanCompare并传入两个Stock实例以查看它是否为有效比较,然后将它们传递到Compare以执行比较。

+0

谢谢你的详细答案。 –