给定以下类:
public interface ISession {}
public class Session : ISession
{
internal Uri ServerUri { get; private set; } // not in interface obviously
}
现在,我在同一项目中有另一个依赖于
Session
的类:public interface IDataClass {}
internal DataClass : IDataClass
{
private readonly Session _session;
public DataClass(ISession session)
{
_session = (Session) session;
}
// some more methods that access the internal property _session.ServerUri
// and call methods on the session object
// ...
}
因此,实际上Session类非常复杂。对于
DataClass
的单元测试,我将构造函数参数设置为ISession
,因此我能够模拟依赖关系并验证ISession
模拟中的某些方法调用。但是,
DataClass
中的某些方法必须访问_session.ServerUri
属性,因此该字段的类型必须为Session
而不是ISession
。我还可以使类型为
ISession
的字段,并在每次访问内部属性时强制转换该字段,这将使在此特定位置更加清楚为什么甚至需要具体的internal
类。每当我以上述方式实现强制转换时,我都会以某种方式想知道,如果采用更好的代码设计,是否可以避免强制转换。通常,我找到了一种更好的方法并摆脱了演员表。
但是上面的例子呢?这是好的代码设计吗?还是有更清洁的方法?我只是觉得以上述方式初始化构造函数的字段很奇怪。
最佳答案
您是正确的,因为这样的转换容易出错,因为编译器没有简单的方法来告诉它将要失败。
但是,问题的根源似乎在于缺乏对ServerUri
属性的访问权限,因此您添加了强制转换作为解决方法。如果是这样,您应该可以同时使用两种方法-保留接口,并可以访问属性(如果可以添加新接口):
public interface ISessionWithServerUri : ISession { // Come up with a better name
Uri ServerUri {get;}
}
现在,您的
Session
类可以实现ISessionWithServerUri
,让您将_session
的声明从Session
类更改为ISessionWithServerUri
接口:internal DataClass : IDataClass
{
private readonly ISessionWithServerUri _session;
public DataClass(ISessionWithServerUri session)
{
_session = session; // Look, no cast!
}
// some more methods that access the internal property _session.ServerUri
// and call methods on the session object
// ...
}