让我们说我想做几节课以确定代理人的行为 好的做法是为它们建立一些通用接口,这样的接口(简化)可能如下所示:
interface IModel
{
void UpdateBehaviour();
}
此类模型的全部或至少大部分都有一些参数,但一个模型的参数可能与其他模型的参数没有任何共同之处。
我想有一些加载参数的常用方法。
问题
最好的方法是什么?
是否只是将方法void LoadParameters(对象参数)添加到IModel?
或者创建空接口IParameters并添加方法void LoadParameters(IParameters参数)?
这是我提出的两个想法,但我不喜欢其中任何一个。
答案 0 :(得分:3)
当您要使用通用代码来处理该接口时,使用通用接口才有意义。
在这种情况下,根据定义,类之间存在某些。
请记住,接口是一个契约,但它们(在概念上)提供的不是合同而不是继承。不是形成对象层次结构,而是使用接口定义对象是另一个对象的某种具体形式,而是提供一个契约,表明该对象可以以特定方式使用,或以特定方式执行。
在您的情况下,IParameterBag
或类似的界面可能有意义。将其与基类库中的ISerializable
进行比较。在那里,你有一个可以通过任何东西实现的界面 - 但总是以单一方式处理。
答案 1 :(得分:2)
Map
中,但这不是编译时安全的。setParameters(..)
方法,该方法需要IParameters
(不定义方法),并在每个特定实现中使用向下转换第二个选项的示例是(Java)CertPathValidator
,它将CertPathParameters
作为输入,不定义任何方法(除了clone()
)
答案 2 :(得分:1)
前段时间我遇到了类似的问题,我在两种解决方案(java中的代码)之间进行选择:
public abstract class Model {
public Model (Map<String, String> initParams) { }
}
and
public abstract class Model {
public Model (InitParams params) { }
}
其中InitParams是一个标记接口,每个具体的Model子类具有不同的实现。
答案 3 :(得分:1)
听起来您可能想要使用标记接口并使用Factory初始化并返回IModel的具体实例。
答案 4 :(得分:1)
1)将LoadParamsXml方法添加到接口
2)创建一个基类ModelBase
3)使用LINQToXml来解析xml
4)使用反射将xml属性分配给实体的公共字段
public override bool LoadParamsXml(string source)
{
XDocument doc = XDocument.Parse(source, LoadOptions.PreserveWhitespace);
var parameters = from u in doc.Descendants("parameterType")
select new
{
id = (int)u.Attribute("id"),
name = u.Attribute("name").Value,
value = u.Attribute("value").Value,
typeId = (int)u.Attribute("typeId"),
nullValue = u.Attribute("nullValue").Value
};
//...
//..
foreach (var item in parameters)
{
SetProperty<T>(this, item.name, item.value);
}
return true;
}
protected virtual void SetProperty<T>(T obj, string propertyName, string value) where T : IModel
{
typeof(T).GetProperty(propertyName).SetValue(obj, value, null);
}
答案 5 :(得分:0)
如果参数没有任何共同点,那么它们可能不应该被接口引用。以下是解决此问题的一种方法:
AgentA agentA = new AgentA();
agentA.setFooParameter("someValue");
someMethod(agentA);
AgentB agentB = new AgentB();
agentB.setBarParameter(true);
someMethod(agentB);
其中someMethod接受代理的接口而不是具体的类
public void someMethod(IModel genericAgent)
{
...
}
本质上,将代理(它们都扩展为IModel)实例化为具体类(而不是IModel agentA = new AgentA();
),在具体类上设置所需的参数,然后传递接口而不是具体类。 / p>