- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试理解和应用 SOLID 原则。关于依赖倒置原则,这是否意味着禁止对对象进行组合/聚合?因此必须始终使用接口(interface)来访问另一个类方法?
我的意思是:
class ServiceClass {
void serviceClasshelper();
}
class MainClass {
void MainClass(ServiceClass service); // To use serviceClasshelper
}
必须改为:
class ServiceInterface {
virtual void interfaceHelper() =0;
}
class ServiceClass : public ServiceInterface {
void serviceClasshelper();
void interfaceHelper() { serviceClasshelper(); };
}
class MainClass {
void MainClass(ServiceInterface service); // Uses interfaceHelper
}
我认为(或者至少我希望)我理解这个原理。但是想知道是否可以这样改写。事实上,我读到的有关 DIP 的文章建议使用接口(interface)。
谢谢!
最佳答案
基本上,DIP 的主要思想是:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
如您所见,它说的是应该而不是必须。它不禁止你做任何事情。
如果您的类组合/聚合到
其他特定的类
(不是接口(interface)/抽象类
),那很好!您的代码仍会编译和运行,不会显示任何警告告诉您:“嘿,您违反了 DIP”。所以我认为您的问题的答案是:不,不是。
假设您的系统由一千个类组成,您可以只将 DIP 应用于 2 个类,并让其中一个依赖于第三个特定类(不是接口(interface)/抽象类
)。只要你的问题解决了,什么都不重要。因此,请尽量使您的解决方案简短明了 -> 易于理解。相信我,当您在 1 个月后回顾您的解决方案时,您会发现它很有值(value)。
DIP 是一个指南,它告诉您在遇到一组特定问题时该怎么做才能解决这些问题。这不是一个神奇的指南,它是有代价的:复杂性。您应用 DIP 的次数越多,您的系统就会越复杂。所以明智地使用它。为了进一步支持这一点,我建议您查看此引用资料(摘自 Head First: Design Patterns
一书)。访问此 link (它是一个 PDF 文件)并在顶部栏导航到页面 635/681
。或者,如果您足够懒惰,只需阅读以下引述:
Your Mind on Patterns
The Beginner uses patterns everywhere. This is good: the beginner gets lots of experience with and practice using patterns. The beginner also thinks, “The more patterns I use, the better the design.” The beginner will learn this is not so, that all designs should be as simple as possible. Complexity and patterns should only be used where they are needed for practical extensibility.
As learning progresses, the Intermediate mind starts to see where patterns are needed and where they aren’t. The intermediate mind still tries to fit too many square patterns into round holes, but also begins to see that patterns can be adapted to fit situations where the canonical pattern doesn’t fit.
The Zen mind is able to see patterns where they fit naturally. The Zen mind is not obsessed with using patterns; rather it looks for simple solutions that best solve the problem. The Zen mind thinks in terms of the object principles and their trade-offs. When a need for a pattern naturally arises, the Zen mind applies it knowing well that it may require adaptation. The Zen mind also sees relationships to similar patterns and understands the subtleties of differences in the intent of related patterns. The Zen mind is also a Beginner mind — it doesn’t let all that pattern knowledge overly influence design decisions.
最后,我将向您介绍一个使用 DIP 的四人组设计模式:Strategy
示例问题:一个角色
可以使用3种武器:手
、剑
和枪
。他(角色
)可以随时更换他当前的武器。
分析:这是一个很典型的问题。棘手的部分是如何在运行时处理武器交换。
候选解决方案与策略:(只是草图):
weapon = new Hand();
weapon.Attack(); // Implementation of Hand class
weapon = new Sword();
weapon.Attack(); // Implementation of Sword class
weapon = new Gun();
weapon.Attack(); // Implementation of Gun class
其他使用 DIP 的设计模式和框架:
关于c++ - 固体 : Does DIP mean that composition/aggreation to an object is forbidden?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40573392/
我遵循了一本名为“Sitepoint Full Stack Javascript with MEAN”的书中的教程,我刚刚完成了第 6 章,应该已经创建了一个带有“数据库”的“服务器”。数据库只不过是
在 Jquery 中,我创建两个数组,一个嵌入另一个数组,就像这样...... arrayOne = [{name:'a',value:1}, {name:'b',value:2}] var arra
这个问题在这里已经有了答案: What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wa
我被放在别人的代码上,有一个类用作其他组件的基础。当我尝试 ng serve --aot(或 build --prod)时,我得到以下信息。 @Component({ ...,
我正在测试一些代码,并使用数据创建了一个 json 文件。 问题是我在警报中收到“[object Object],[object Object]”。没有数据。 我做错了什么? 这是代码:
我想打印 [object Object],[object Object] 以明智地 "[[{ 'x': '1', 'y': '0' }, { 'x': '2', 'y': '1' }]]"; 在 ja
我有一个功能 View ,我正在尝试以特殊格式的方式输出。但我无法让列表功能正常工作。 我得到的唯一返回是[object Object][object Object] [object Object]
在使用优秀的 Sim.js 和 Three.js 库处理 WebGL 项目时,我偶然发现了下一个问题: 一路走来,它使用了 THREE.Ray 的下一个构造函数: var ray = new THRE
我正在使用 Material UI 进行多重选择。这是我的代码。 {listStates.map(col => (
我的代码使用ajax: $("#keyword").keyup(function() { var keyword = $("#keyword").val(); if (keyword.
我遇到了下一个错误,无法理解如何解决它。 Can't resolve all parameters for AuthenticationService: ([object Object], ?, [o
我正在尝试创建一个显示动态复选框的表单,至少应选中其中一个才能继续。我还需要获取一组选中的复选框。 这是组件的代码: import { Component, OnInit } from '@angul
我正在开发 NodeJs 应用程序,它是博客应用程序。我使用了快速验证器,我尝试在 UI 端使用快速闪存消息将帖子保存在数据库中之前使用闪存消息验证数据,我成功地将数据保存在数据库中,但在提交表单后消
我知道有些人问了同样的问题并得到了解答。我已经查看了所有这些,但仍然无法解决我的问题。我有一个 jquery snipet,它将值发送到处理程序,处理程序处理来自 JS 的值并将数据作为 JSON 数
我继承了一个非常草率的项目,我的任务是解释为什么它不好。我注意到他们在整个代码中都进行了这样的比较 (IQueryable).FirstOrDefault(x => x.Facility == fac
我只是在删除数组中的对象时偶然发现了这一点。 代码如下: friends = []; friends.push( { a: 'Nexus', b: 'Muffi
这两个代码片段有什么区别: object = nil; [object release] 对比 [object release]; object = nil; 哪个是最佳实践? 最佳答案 object
我应该为其他人将从中继承的第一个父对象传递哪个参数,哪个参数更有效 Object.create(Object.prototype) Object.create(Object) Object.creat
我在不同的对象上安排不同的选择器 [self performSelector:@selector(doSmth) withObject:objectA afterDelay:1]; [self per
NSLog(@"%p", &object); 和 NSLog(@"%p", object); 有什么区别? 两者似乎都打印出一个内存地址,但我不确定哪个是对象的实际内存地址。 最佳答案 这就是我喜欢的
我是一名优秀的程序员,十分优秀!