出于松散耦合和测试的目的,我现在正在用接口和抽象类替换具体的引用,但是我在理解以下场景时遇到了麻烦:
假设我有两个具体的业务层对象,它们的唯一目的是调用数据访问逻辑方法并在传递回控制器(ASP.NET MVC4)之前对结果执行逻辑,这两个对象分别称为FordCar和CitroenCar。它们都继承自Car抽象类,后者继承自ICar接口:
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);
    }
}因为DAL包含适用于所有汽车的逻辑,所以我也为此实现了一个接口和抽象类:
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类来维护-因为它拥有大多数常见的功能-而当它没有在那里定义时调用TurnOnScreenHeating()呢?这需要一个特定于汽车类型的DAL类,这违背了我的目标。
我想我的问题是:给出许多具有大部分共享功能的域对象,在尝试松散耦合和依赖注入时,我如何适应奇怪的独特功能?
因为在我的控制器中,我希望这样做:
public class FordCarController : Controller
{
    private Car BLLMethods;
    public FordCarController()
    {
        // Init concrete type
        this.BLLMethods = new FordCar();
    }
    public ActionResult DoHeating()
    {
        this.BLLMethods.TurnOnScreenHeating();
        return View();
    }
}对于错综复杂的场景和糟糕的标题,我深表歉意。
发布于 2014-04-23 00:02:13
我有几点看法。我希望其中的一到两个能适用于你遇到的特定情况:
Car的CitroenCar和一辆FordCar,不如让一辆带有Make属性的Car来告诉你它是哪种车。IHaveWindscreenHeater).ICar类实现一个bool CanHeatWindscreen{get;}属性,以及一个TurnOnScreenHeating()方法。后一种方法要么什么都不做,要么在没有heating.的汽车中抛出异常
FordController的事实告诉我,你不能再松散地耦合它:你声明它是为了做与福特汽车有关的事情,所以即使你设法在代码中将它与FordCar类解耦,你在概念上仍然是紧密耦合的。这可能比在代码中使用紧密耦合更危险。根据上面的观察#1,您可能只想使用一个处理所有Car操作的CarController类。https://stackoverflow.com/questions/23223979
复制相似问题