首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构访问遗留系统中存储库的域逻辑

重构访问遗留系统中存储库的域逻辑
EN

Stack Overflow用户
提问于 2009-08-12 08:31:52
回答 4查看 886关注 0票数 7

我正在使用一个具有贫血域模型的遗留系统。

域有以下实体类:CarCarTypeCarComponentCarComponentType

对于其中的每一个,都有一个单独的存储库。还有一些服务可以访问这些存储库,基本上包含所有的逻辑。

我需要实现一个方法来确定供应商是否可以停止使用CarComponentType。逻辑如下:一个组件只有在今天没有该组件的现有汽车时才能停用。

最初,我在一个服务类中实现了这一点。

代码语言:javascript
复制
public boolean canBeDiscontinued(CarComponentType carComponentType) {
    List<Car> cars = carRepository.getCarsWithComponent(carComponentType);
    return cars.isEmpty();
}

这是可行的,但是这个逻辑是从代码中的其他地方使用的。它可能会增长,它看起来像是可以适应CarComponentType类的东西:

代码语言:javascript
复制
public boolean canBeDiscontinued() {
    List<Car> cars = carRepository.getCarsWithComponent(this);
    return cars.isEmpty();   
}

但是,我不能把它放在那里,因为它需要访问存储库(据我所知,对于实体来说,了解数据访问层是一个非常严重的反模式)。在加载组件类型时,我不能加载该类型的所有汽车,因为这可能是数千个对象。我们没有使用任何ORM,所以使一个懒散加载的集合不仅笨重,而且非常容易出错。

像我第一次做的那样,在服务类中使用这个方法更合适吗?这不重要吗?还有别的选择吗?我应该从另一个起点开始重构吗?

还有一个类似的问题,这里。但我的问题与Java有关,因此我认为该解决方案不适用于我的情况。另外,很抱歉预先使用汽车和零部件作为我的领域模型。:)

EN

回答 4

Stack Overflow用户

发布于 2009-08-12 09:04:58

弗雷德里克·盖塞尔的回答是好的,虽然可能有点短。详细说明:在您的示例中,您可以首先为您的规范定义一个接口(请原谅我的C#语法):

代码语言:javascript
复制
public interface ICarSpecification
{
    bool IsSatisfiedBy(CarComponentType carComponentType);
}

然后,您可以创建一个使用您的存储库的ICarSpecification的内隐。就像这样:

代码语言:javascript
复制
public class CanDiscontinueSpecification : ICarSpecification
{
    private readonly CarRepository carRepository;

    public CanDiscontinueSpecification(CarRepository carRepository)
    {
         this.carRepository = carRepository;
    }

    public bool IsSatisfiedBy(CarComponentType carComponentType)
    {
        return this.carRepository.GetCarsWithComponent(carComponentType).Any();
    }
}

您可以在这里停下来,但是我不特别喜欢规范模式的一点是,它不是很容易发现。一种可能的解决方案是将规范注入CarComponentType本身:

代码语言:javascript
复制
public class CarComponentType
{
    private readonly ICarSpecification discontinueSpec;

    public CarComponentType(ICarSpecification discontinueSpec)
    {
        this.discontinueSpec = discontinueSpec;
    }

    public bool CanBeDiscontinued()
    {
        return this.discontinueSpec.IsSatisfiedBy(this);
    }
}

或者,如果您不喜欢在类的每个实例中执行规范,则可以使用方法注入而不是构造器注入:

代码语言:javascript
复制
public bool CanBeDiscontinued(ICarSpecification spec)
{
    return spec.IsSatisfiedBy(this);
}

这样的方法在实现方面并没有真正增加任何价值,但是更容易被发现。

票数 5
EN

Stack Overflow用户

发布于 2009-08-12 08:39:23

这听起来像是规格模式很好的候选人

票数 3
EN

Stack Overflow用户

发布于 2009-08-12 16:54:14

我不认为“能不能停办”这类课程属于任何一门课。谁负责决定一个部件是否可以停用?不是汽车或汽车部件。我认为您在服务中实现的初始方法是正确的。也许您需要一个负责回答有关汽车库存项目的问题的CarInventoryManagementService,如:

代码语言:javascript
复制
carsUsingComponent( CarComponent comp )
canComponentBeDiscontinued( CarComponent comp )
etc

如果代码中有多个地方需要询问与库存相关的问题,比如您的"canBeDiscontinued“,那么创建一个具有这种责任的服务可能是有意义的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1264944

复制
相关文章

相似问题

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