哪种设计模式可以实现这种架构

时间:2014-04-24 08:58:08

标签: c# oop design-patterns inheritance architecture

我有以下对象:

  • 库存
  • 计数器
  • 等...

所有这些对象都称为指标,并具有共同属性(Id,Name,Value ...)。 每个实体都有自己的属性:

  • 公式:FormulaExpression,FormulaCode,OperandsList ...
  • 股票:StockValue,StockLimit ......
  • 专柜:CounterIndex ......
  • 等...

所以逻辑上,我必须创建包含公共属性的指标类,并且对于每个实体,我必须创建一个继承自指标的类。

公式是一个特殊指标,可以包含任何类型的指标。公式的指标被命名为操作数。

操作数对象具有以下属性: operandId,operandCode,operandIndex

当我想列出公式操作数时,我想获得从指标,操作数和实体类型继承的对象(例如,创建一个具有指标属性,操作数属性和股票属性的对象)

哪种设计模式或哪种架构允许我有这种行为?


解释更多问题

实体(FormulastockCounter ..)为Indicators,不必要OperandsOperands为{{1也是。对象Indicators是实体的原始类型,我们可以创建一个Indicator,然后将它装饰成Indicator例如,然后装饰它成为Formula当它被添加到另一个Operand

2 个答案:

答案 0 :(得分:0)

我在这里发布的内容可能看起来像很多代码,但实际上非常简单。

大多数属性和构造函数都是为了简化main函数中的脚本。

基本概念是为操作数创建Generic Class,其中包含对其创建的基础Indicator对象的引用。

在空项目中测试此代码,从输出中可以很容易理解。

class Indicator{
    // Common properties
}
class Counter : Indicator{
    public int CounterIndex;
    public Counter(int cI){
        CounterIndex = cI;
    }
    public void Print()
    {
        Console.WriteLine("CounterIndex: {0}", CounterIndex);
    }
}
class Operand{
    // Common operand properties
}
class Operand<T> : Operand{
    public T BaseIndicator;
    public Operand(T bI){
        BaseIndicator = bI;
    }
}
class Formula : Indicator{
    public string FormulaExpression;
    public int FormulaCode;
    public List<Operand> OperandsList = new List<Operand>();

    public Formula(string fE, int fC){
        FormulaExpression = fE;
        FormulaCode = fC;
    }

    public void Print ()
    {
        Console.WriteLine ("FormulaExpression: {0}; FormulaCode: {1}",
                           FormulaExpression, FormulaCode);
        if (OperandsList.Count == 0) {
            return;
        }
        Console.WriteLine("Begin Operands: ");
        foreach(Operand o in OperandsList){
            if(o is Operand<Counter>){
                Operand<Counter> cO = o as Operand<Counter>;
                cO.BaseIndicator.Print();
            }else if(o is Operand<Formula>){
                Operand<Formula> fO = o as Operand<Formula>;
                fO.BaseIndicator.Print();
            }else{
                // I'ts a simple Indicator
            }
        }
        Console.WriteLine("End Operands");
    }
}
class MainClass
{
    public static void Main (string[] args)
    {
        Counter c1 = new Counter(2);
        Counter c2 = new Counter(3);
        Formula f1 = new Formula("a + b", 7);
        Formula f2 = new Formula("a * b", 10);

        Formula f = new Formula("a ^ b", 32);
        f.OperandsList.Add(new Operand<Counter>(c1));
        f.OperandsList.Add(new Operand<Formula>(f1));
        f.OperandsList.Add(new Operand<Counter>(c2));
        f.OperandsList.Add(new Operand<Formula>(f2));
        f.Print();
        Console.ReadLine();
    }
}

答案 1 :(得分:0)

执行此操作的最佳方法是使用由多态分派填充每个操作数的expando对象。 expando对象允许您添加自定义属性,并且多态分派允许您关闭操作数更改代码。

您首先要使用包含基本元素的操作数的基类

public abstract class Operand
{
    public int Id { get; set; }
    public string Name { get; set; }

    public dynamic BuildObject()
    {
        dynamic o = new ExpandoObject();
        o.Id = Id;
        o.Name = Name;
        AddPropertiesToObject(o);
        return o;
    }

    protected internal abstract void AddPropertiesToObject(dynamic o);
}

然后添加新的Operand类型非常简单,因为您可以独立控制要添加的内容:

public class Stock : Operand
{
    public double StockValue { get; set; }

    protected internal override void AddPropertiesToObject(dynamic o)
    {
        // I decided to ignore the base class Id and Name
        // adding them would be trivial, but may not be what you need since 
        // it would overwrite the base values...
        // To add them you would have to wrap this virtual method call with
        // a call to a function doing the insertion in the base class 
        o.StockValue = StockValue;
    }
}

Formula对象将简单地迭代所包含的操作数并依次调用它们AddPropertiesToObject(当然它也可以添加自己的数据,但是对于示例我没有包含任何数据)

public class Formula : Operand
{
    public List<Operand> InnerOperands { get; set; }

    protected internal override void AddPropertiesToObject(dynamic o)
    {
        foreach (var op in InnerOperands)
        {
            op.AddPropertiesToObject(o);
        }
    }
}