我有以下对象:
所有这些对象都称为指标,并具有共同属性(Id,Name,Value ...)。 每个实体都有自己的属性:
所以逻辑上,我必须创建包含公共属性的指标类,并且对于每个实体,我必须创建一个继承自指标的类。
公式是一个特殊指标,可以包含任何类型的指标。公式的指标被命名为操作数。
操作数对象具有以下属性: operandId,operandCode,operandIndex
当我想列出公式操作数时,我想获得从指标,操作数和实体类型继承的对象(例如,创建一个具有指标属性,操作数属性和股票属性的对象)
哪种设计模式或哪种架构允许我有这种行为?
解释更多问题
实体(Formula
,stock
,Counter
..)为Indicators
,不必要Operands
,Operands
为{{1也是。对象Indicators
是实体的原始类型,我们可以创建一个Indicator
,然后将它装饰成Indicator
例如,然后装饰它成为Formula
当它被添加到另一个Operand
。
答案 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);
}
}
}