出于松散耦合和测试的目的,我现在用接口和抽象类替换具体的引用,但是我无法理解以下场景:
假设我有两个具体的业务层对象,其唯一目的是在传递回控制器(ASP.NET MVC 4)之前调用数据访问逻辑方法并对结果执行逻辑,称为FordCar
和{{ 1}}。它们都继承自CitroenCar
抽象类,它继承自Car
接口:
ICar
因为DAL包含适用于所有汽车的逻辑,我也为此实现了一个接口和抽象类:
public interface ICar
{
ICarDAL DAL;
bool StartEngine();
bool StopEngine();
Driver ChangeDriver(Driver d);
}
public abstract class Car : ICar
{
private ICarDAL DAL;
public virtual Car(ICarDAL DALInstance)
{
this.DAL = DALInstance;
}
public virtual bool StartEngine()
{
return this.DAL.UpdateEngine(true);
}
public virtual bool StopEngine()
{
return this.DAL.UpdateEngine(false);
}
public virtual Driver ChangeDriver(Driver d)
{
return this.DAL.UpdateDriver(d);
}
}
现在说public interface ICarDAL<T>
{
T EFContext;
bool UpdateEngine(bool b);
Driver UpdateDriver(Driver d);
}
public abstract class CarDAL<T> : ICarDAL<T>
{
private T EFContext;
public virtual bool UpdateEngine(bool b)
{
try
{
using(T db = new T())
{
// Perform DB update
// return true
}
}
catch(Exception e)
{
// Handle and return false
}
}
// and so on..
}
能够打开FordCar
没有的挡风玻璃加热。这是我失去视线的地方,为了保持一致,我希望我必须为CitroenCar
实现额外的小接口和抽象类,但我如何能够使用抽象的FordCar
类来维护 - 它主要包含常用功能 - 但是当它没有在那里定义时调用CarDAL
?这需要特定于汽车类型的DAL类,这会击败我的目标。
我想我的问题是:给定大量具有共享功能的域对象,在尝试松散耦合和依赖注入时如何适应奇怪的独特功能?
对于我的控制器,我希望这样做:
TurnOnScreenHeating()
为复杂的情景和糟糕的头衔道歉。
答案 0 :(得分:4)
我有一些观察。我希望他们中的一两个能适用于您遇到的具体情况:
CitroenCar
属性FordCar
来告诉您,而不是从Car
继承Car
和Make
。它是哪种车。IHaveWindscreenHeater
)。ICar
类实现bool CanHeatWindscreen{get;}
属性,以及TurnOnScreenHeating()
方法。后一种方法可以做任何事情,或者在没有暖气的汽车中抛出异常。FordController
打电话的事实告诉我你不能再松散地说这个:你宣称要做与福特汽车有关的事情,所以即使你设法将它与代码中的FordCar
类,你仍然在概念上紧密耦合。这可能比在代码中紧密耦合更危险。在上面观察#1之后,您可能只想使用一个处理所有CarController
操作的Car
类。