我从事过几个项目,我们非常严格地对接口进行编码,这些接口很少或没有接口属性的可变性。然后,我发现自己编写的类提供了以任何方式改变对象并返回它的任意能力。
这是一个例子:
public interface IOlapCube
{
String CubeName {get;}
IEnumerable<IDimension> Dimensions{get;}
IEnumerable<IMeasure> Measures {get;}
IEnumerable<IMeasureGroup> MeasureGroups {get;}
}
public class OlapCubeRW : IOlapCube
{
public String CubeName {get;set;}
private List<IDimension> _dimensionList;
public IList<IDimension> Dimensions{get{return this._dimensionList;}}
IEnumerable<IDimension> IOlapCube.Dimensions{get{return this.Dimensions;}}
//... similar for the rest
}
这是DTO吗?我应该在哪里定义这个类?它应该与 IOlap 立方体在同一个组件中吗?如果是这样,它应该在同一个名称空间中吗?我发现使用 IOlapCube 的几个项目可以从 RW 类中受益,我讨厌重新实现每个项目中相同的内部类。这些类对于单元测试也很有用,我可以创建任意派生类并通过接口引用它。例如,对于每个接口,都有一个关联的 IEqualityComparer,当我可以构造两个具有我想要的任何形状的对象并比较它们时,比较器的单元测试相当简单。
这些通常也用于编辑实体。我可以将实体传递给表单,并将其复制到其中一个对象中。然后表单可以任意更改对象,我可以使用外部类进行验证,例如 bool OlapCubeValidator.IsValid(IOlapCube cubeToValidate); 如果验证通过,则将更改复制回实体(可能是此 RW 类上的实体代理,现在已确保有效)。
将它们放在与 IOlap 相同的位置感觉不对,只是因为客户端似乎不应该启动其中一个并使用它,但我认为如果我可以在外部执行验证,它不会有任何伤害。这个特定的项目是公司内部的,所以我们不必担心恶意,只是懒惰的编程。如果这是一个公开的图书馆,它会改变什么吗?
编辑 重要的是要注意这个接口层次结构(IOlapCube > IDimension、IMeasureGroup、IMeasure > IHierarchy > ILevel > IMember)不公开任何方法或其他功能;它们只提供数据(例如名称、子对象、IsVisible、...)。没有像 IQueryable(T) ExecuteQuery(T)(ICriteria(T) 标准) 这样的方法。验证和相等定义是外部接口(例如,IEqualityComparer)的一部分。