首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在给定复杂继承的情况下保持一致的松散耦合

在给定复杂继承的情况下保持一致的松散耦合
EN

Stack Overflow用户
提问于 2014-04-22 23:36:24
回答 1查看 208关注 0票数 1

出于松散耦合和测试的目的,我现在正在用接口和抽象类替换具体的引用,但是我在理解以下场景时遇到了麻烦:

假设我有两个具体的业务层对象,它们的唯一目的是调用数据访问逻辑方法并在传递回控制器(ASP.NET MVC4)之前对结果执行逻辑,这两个对象分别称为FordCarCitroenCar。它们都继承自Car抽象类,后者继承自ICar接口:

代码语言:javascript
运行
复制
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包含适用于所有汽车的逻辑,所以我也为此实现了一个接口和抽象类:

代码语言:javascript
运行
复制
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类,这违背了我的目标。

我想我的问题是:给出许多具有大部分共享功能的域对象,在尝试松散耦合和依赖注入时,我如何适应奇怪的独特功能?

因为在我的控制器中,我希望这样做:

代码语言:javascript
运行
复制
public class FordCarController : Controller
{
    private Car BLLMethods;

    public FordCarController()
    {
        // Init concrete type
        this.BLLMethods = new FordCar();
    }

    public ActionResult DoHeating()
    {
        this.BLLMethods.TurnOnScreenHeating();
        return View();
    }
}

对于错综复杂的场景和糟糕的标题,我深表歉意。

EN

回答 1

Stack Overflow用户

发布于 2014-04-23 00:02:13

我有几点看法。我希望其中的一到两个能适用于你遇到的特定情况:

  1. 通常更倾向于组合而不是继承。换句话说,与其拥有一辆继承自CarCitroenCar和一辆FordCar,不如让一辆带有Make属性的Car来告诉你它是哪种车。
  2. ,而不是基于你对特定类型车的了解来实现功能,试着专注于功能检查。您可以采用几种不同的方法。例如:
    1. 使对象实现特定于功能的接口(IHaveWindscreenHeater).
    2. Make主ICar类实现一个bool CanHeatWindscreen{get;}属性,以及一个TurnOnScreenHeating()方法。后一种方法要么什么都不做,要么在没有heating.

的汽车中抛出异常

  1. 你调用你的控制器FordController的事实告诉我,你不能再松散地耦合它:你声明它是为了做与福特汽车有关的事情,所以即使你设法在代码中将它与FordCar类解耦,你在概念上仍然是紧密耦合的。这可能比在代码中使用紧密耦合更危险。根据上面的观察#1,您可能只想使用一个处理所有Car操作的CarController类。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23223979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档