我正在使用具有贫血领域模型的遗留系统。
域具有以下实体类:Car、CarType、CarComponent、CarComponentType。
对于其中的每一个,都有一个单独的存储库。还有许多服务可以访问这些存储库并包含基本上所有的逻辑。
我需要实现一种方法来确定供应商是否可以停产 CarComponentType。逻辑如下:只有当今天没有现有汽车使用该组件时,该组件才能停产。
最初,我在服务类中实现了它。
public boolean canBeDiscontinued(CarComponentType carComponentType) {
List<Car> cars = carRepository.getCarsWithComponent(carComponentType);
return cars.isEmpty();
}
这行得通 - 但代码中的其他几个地方也使用了这个逻辑。它可能会变大,而且它看起来像是适合 inside CarComponentType 类的东西:
public boolean canBeDiscontinued() {
List<Car> cars = carRepository.getCarsWithComponent(this);
return cars.isEmpty();
}
但是,我不能把它放在那里,因为它需要访问存储库(据我所知,这是一个非常严重的反模式,让实体意识到数据访问层)。加载组件类型时,我无法加载该类型的所有汽车,因为那可能有数千个对象。我们没有使用任何 ORM,因此制作一个延迟加载的集合不仅体积庞大而且非常容易出错。
像我第一次那样在服务类中实际使用此方法是否更合适?这不重要吗?还有其他选择吗?我应该从另一个起点开始重构吗?
有个类似的问题here .但我的问题与 Java 有关,所以我认为该解决方案不适用于我的情况。另外,提前抱歉使用汽车和组件作为我的领域模型。 :)
最佳答案
Frederik Gheysel 的回答很好,尽管可能有点短。详细说明:在您的情况下,您可以从为您的规范定义一个接口(interface)开始(请原谅我的 C# 语法):
public interface ICarSpecification
{
bool IsSatisfiedBy(CarComponentType carComponentType);
}
然后您可以创建一个使用您的存储库的 ICarSpecification 实现。像这样:
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();
}
}
您可以就此打住,但我不太喜欢规范模式的一点是它不太容易被发现。一种可能的解决方案是将规范注入(inject) CarComponentType 本身:
public class CarComponentType
{
private readonly ICarSpecification discontinueSpec;
public CarComponentType(ICarSpecification discontinueSpec)
{
this.discontinueSpec = discontinueSpec;
}
public bool CanBeDiscontinued()
{
return this.discontinueSpec.IsSatisfiedBy(this);
}
}
或者,如果您不想在类的每个实例中都携带规范,您可以使用方法注入(inject)而不是构造函数注入(inject):
public bool CanBeDiscontinued(ICarSpecification spec)
{
return spec.IsSatisfiedBy(this);
}
这样的方法在实现方面并没有真正增加任何值(value),但更容易被发现。
关于java - 重构访问遗留系统中存储库的域逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1264944/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
我正在使用RubyonRails3.2.2,我想从我的模型/类中“提取”一些方法。也就是说,在不止一个类/模型中,我有一些方法(注意:方法与用户授权相关,并被命名为“CRUD方式”),这些方法实际上是相同的;所以我认为DRY方法是将这些方法放在“共享”模块或类似的东西中。实现该目标的常见且正确的方法是什么?例如,我应该将“共享”代码放在哪里(在哪些目录和文件中)?如何在我的类/模型中包含提到的方法?你有什么建议?注意:我正在寻找“RubyonRails制作东西的方式”。 最佳答案 一种流行的方法是使用ActiveSupport关注点
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt