这是我在金融行业的问题领域:

资产
==========
资产母公司
assetID
+ compareTo(Asset anotherAsset)

投资组合:资产
-----------------
名称
风险极限
上市股票
+ compareTo(Asset anotherAsset)
+ Composite.CompareTo(投资组合,ComparisonRules)。

库存:资产
-------
市场

公司
+ compareTo(Asset anotherAsset)

AnotherStock:股票
--------------------
一些其他财产
+ compareTo(Asset anotherAsset)


我已经将复合模式应用于* Portfolio * s中的* Stock * s结构。我想要一种干净的方法来定制此复合材料的compareTo方法。也就是说,AnotherStock将始终与另一个AnotherStock(从股票到股票)进行比较。在我看来,这是一种策略模式。

我想做类似以下的事情(伪代码)

差异= Composite.CompareTo(anotherComposite,CompareRules)。

Composite.CompareTo将类似于:

比较规则。比较(this.Stocks [currentAssetID],otherComposite [currentAssetID])


ComparisonRules.Compare(资产a,资产b)会像这样丑陋:

if(a是股票而b是股票):转换为股票并进行基于股票的比较
否则,如果(a是AnotherStock,b是AnotherSTock):转换为AnotherStock


有没有一种方法可以编写ComparisonRules,而我不必向下转换,仍然可以提供自定义的ComparisonRules对象?

最佳答案

从规则的角度来看,听起来您需要的是泛型。如果您按照以下方式定义内容:

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


这将确保仅接受TStock或以下的类型。例如,如果我有一个ComparisonRule<AnotherStock>,则只能传递AnotherStock或以下的类型。但是,如果希望能够定义一个可以比较,但不是Stock。您应该考虑拥有一个共同的祖先,但是具体的股票类型应该在不同的继承树中。

换句话说,您有:

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


这将允许您定义可以将任何AnotherStockStock进行比较的规则,或者只能将ComparisonRule<Stock>OneStock进行比较的规则。

但是,这并不能帮助您更好地了解如何将哪些ComparisonRule<OneStock>对象传递给更高级别的规则。为此,您将需要能够定义Stock的特定版本,我们可以使用以下接口进行操作:

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);
}


现在,严格来说,您的问题询问如何在不降低转换率的情况下执行此操作(再次严格地说,这是不可能的)。但是,这应该使您不必在每个实现中都这样做。例如,比较两个ComparisonRule实例的简单规则是:

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


在较高级别(即在AnotherStock中),您可以简单地保留Portfolio列表作为规则,然后可以调用IComparisonRule并传入两个CanCompare实例以查看它是否是有效的比较,然后将它们传递到Stock以便进行比较。

09-25 20:14