- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道以下是一个主观问题,但您的指导方针确实有助于我追求干净、可测试的代码。
请考虑以下示例,我认为它违反了一系列设计原则。
public class OfferEligibilityCheckerServiceImpl implements OfferEligibilityCheckerService, Refreshable{
private Map<String, OfferCriteria> offerIdToOfferCriteriaMap;
private OffersAccessorService offersAccessorService
public OfferEligibilityCheckerServiceImpl (OffersAccessorService offersAccessorService ){
this.offersAccessorService = offersAccessorService;
initValidOfferIdSet();
}
protected void initOfferIdToOfferCriteriaMap(){
offerIdToOfferCriteriaMap = offersAccessorService.get..Criteria();
}
//REAL BUSINESS LOGIC, i.e. this is why the service is used by clients!!
@Override
public boolean isUserEligible(String offerId, UserInfo userInfo){
offerCriteria = offerIdToOfferCriteriaMap.get(offerId);
return offerCriteria.isEligible(userInfo); // let's not worry about NPE
}
// Gets invoked at regular intervals by some scheduler, say Spring.
@Override // from Refreshable
public void refresh(){ // ANOTHER responsibility
initOfferIdToOfferCriteriaMap();
}
}
我觉得上面的代码在很多层面上都是错误的,但我缺乏足够深入的知识来说服其他人它是平庸的/不可测试的。
据我所知,上述设计的问题在于它看起来可测试,因为某些部分可以替换,但它有点违反所有“可测试设计”准则。
我和其他人之间的对话。
我:构造函数中的复杂逻辑。
其他:不,我正在从构造函数中调用 protected 方法,如果您需要测试替身,可以覆盖该方法。
我:违反得墨忒耳法则 - 要求确切的东西,而不是中介。
其他:了解“代码到接口(interface)”的强大功能。我正在传递一个 serviceImpl,而构造函数需要一个服务。所以我总是可以在测试时进行替换,这样 serviceImpl 就不会在单元测试期间真正与 DAO/数据库对话。
我:违反 SRP - 处理业务逻辑,处理让我在构建过程中得到我自己的东西,处理让我恢复精神。
其他:没关系!我不想将这个类分成 3 个类,并承担安排它们/连接它们的开销。
我:混合业务逻辑和对象构建逻辑。
其他:我什至不明白你的意思。
问题 1)我说得对吗?
我可能没有指出正确的问题或没有以正确的方式表达它们。
如果您能列出我们在未来使用上述设计可能面临的问题,那就太好了。如果您能解决或验证我的第 1 点到第 4 点,那就更好了。
问题2:你会如何重新设计它(包括布线部分)?
最佳答案
这就是一般设计模式和原则的问题 - 过分关注它们会使我们远离编写代码/生产软件的真正目的......这是为了解决业务问题。
首先,让我告诉你为什么这段代码没问题:
话虽如此,结论很明显 - 除了可能违反 SRP 之外,没有太大的改进空间;令人耳目一新的部分确实可以在不同的组件中。但是,然后您将有两个必须连接在一起(正如您的同事也提到的那样 - 事实上,此类已经这样做了)。有人可能会争辩说这是要走的路,但是当类/职责这么小时,付出的努力通常得不偿失,而且往往会给代码带来不必要的复杂性。
您的第 1、2 和 4 点并不是重新设计的最佳论据。 SRP 是对的。但是,您的同事的论点更有说服力 - 将这么小的类(class)分成 3 个很可能不会有任何好处,而且肯定会让人稍后提出问题。
总而言之,值得记住的是在某些时候必须有人阅读您的代码。您需要知道何时停止关注模式和完美设计,以及何时开始关注让您的代码尽可能简单以供其他人遵循。
关于oop - 违反 SRP、Demeter 法则等的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21348251/
我正在尝试了解如何正确使用被动 View 。在我看来,我在被动 View 上看到的每个例子都违反了德米特法则: //In the presenter code myview.mytextfield.t
如果我有一个包含方法 f 的类 C,该方法将 D 类型的对象(我定义的另一个类)作为参数 如果我在方法f中调用对象D的方法,是否会违反得墨忒耳定律?为什么? 例如: public C { pu
我愿意遵守得墨忒耳法则。但我也想延迟加载一些传递给构造函数的对象。我应该如何实现?通过包装类?传递函数指针? 最佳答案 您实际上可以编写一个通用包装器来完成此操作: template class L
从这里引用:https://en.wikipedia.org/wiki/Law_of_Demeter More formally, the Law of Demeter for functions r
以下代码打破了 Law of Demeter : public class Student extends Person { private Grades grades; public Stu
感觉好像走到了死胡同。如果我理解正确,那么如果我遵循 Law of Demeter我永远无法制作一个返回对象的方法,然后客户端代码调用它。我只是在考虑总是返回一个对象的工厂模式。是的,有返回对象的映射
我有一个简单的 Store 类,其中包含一个 Inventory。 Inventory 包含一个 Item 列表。为了修改 Inventory 中的其中一个 Item,我必须这样写: Store st
public class BigPerformance { public decimal Value { get; set; } } public class Performance
我知道以下是一个主观问题,但您的指导方针确实有助于我追求干净、可测试的代码。 请考虑以下示例,我认为它违反了一系列设计原则。 public class OfferEligibilityCheckerS
我最近才知道 Law of Demeter . 像很多事情一样,我意识到这是我已经在做但没有名字的事情。虽然有几个地方我似乎违反了它。 例如... 我可能有一个地址对象: public class A
在敏捷开发人员的基本技能中,在需求与能力接口(interface)中,第 12 章,我试图理解作者在本章末尾提到的应用分度法则的挑战所提出的主要解决方案。 为了使故事简短。 我们从以下研究案例开始:
我经常发现自己做了很多 delegating . 在Ruby Science ,它说: Many delegate methods to the same object are an indicato
我有点想用 Java 8 流编写 Selenium 页面对象,如下面的代码所述,并收到评论说我的代码违反了 Demeter 法则,因为我在一行中执行了很多操作。我被建议将代码分解为第一个流以收集列表并
我有一个游戏引擎,我将物理模拟从游戏对象功能中分离出来。所以我有一个物理 body 的纯虚拟类 class Body 我将从中导出物理模拟的各种实现。我的游戏对象类看起来像 class GameObj
我对如何避免一对多关联违反得墨忒耳法则感到困惑。假设我有一个这样的模型: class Organization < ActiveRecord::Base has_one :address ha
如果我有一个对象的 ArrayList,那么任何时候我需要调用 ArrayList 成员的任何方法时,我都需要这样做: list.get(i).doSomething(); 这看起来很可疑地违反了 D
我在设计在 SpringMVC/Hibernate Rest Web 应用程序中的 @ManyToMany 集合上运行的服务方法时遇到问题,而不使用违反 Demeter 法则的长方法链。我的应用程序有
这可能是一个幼稚的问题,但是 RSpec 的测试 DSL 是否违反了 Demeter 法则? 这是来自 http://rspec.info 的 RSpec DSL 示例: bowling.score.
假设您有一个类 Car,它有一个 Driver。如果你想访问司机的年龄,你会这样做: @car.driver_age 代替 @car.driver.age 如果您在 Car 模型中委托(delegat
我正在使用一个工具来自动生成按层次结构组织的 XML 文件的类表示形式。 XML 文件是我的应用程序需要能够访问的设置文件(只读)。 如果我将顶级节点(例如,AppSettings)传递给需要访问一项
我是一名优秀的程序员,十分优秀!