Questions tagged «solid»

一组设计原则的助记符:单项责任,开放式,封闭式,Liskov替代,接口隔离,依赖性反转

16
使用单一责任原则时,什么构成“责任”?
显然,“单一责任原则”并不意味着“只做一件事情”。那就是方法的目的。 public Interface CustomerCRUD { public void Create(Customer customer); public Customer Read(int CustomerID); public void Update(Customer customer); public void Delete(int CustomerID); } 鲍勃·马丁说:“班级应该只有一个改变的理由。” 但是,如果您是SOLID的新手,那么很难下定决心。 我写了另一个问题的答案,在那儿我建议责任就像职位,然后用饭店的比喻来阐明我的观点。但这仍未阐明某人可以用来定义其班级职责的一组原则。 你是怎么做到的?您如何确定每个班级应承担的责任,以及如何在SRP中定义责任?

6
SOLID原则和代码结构
在最近的一次工作面试中,除了提供各种原理的基本含义之外,我无法回答有关SOLID的问题。这真的让我很烦。我做了几天值得深入研究的工作,但还没有得出令人满意的总结。 面试问题是: 如果您要看一个我严格遵循SOLID原则的.Net项目,那么您期望在项目和代码结构方面看到什么? 我挣扎了一下,没有真正回答问题,然后轰炸了。 我如何更好地处理这个问题?
149 c#  .net  solid 

10
这是否违反了《里斯科夫换人原则》?
假设我们有一个Task实体列表和一个ProjectTask子类型。任务可以随时关闭,除非ProjectTasks状态为“已启动”的任务无法关闭。用户界面应确保关闭启动选项ProjectTask永远不会可用,但是域中存在一些保护措施: public class Task { public Status Status { get; set; } public virtual void Close() { Status = Status.Closed; } } public class ProjectTask : Task { public override void Close() { if (Status == Status.Started) throw new Exception("Cannot close a started Project Task"); base.Close(); } } 现在,在调用Close()Task时,如果调用ProjectTask处于启动状态,则有可能失败,而如果它是基本Task,则调用不会失败。但这是业务需求。它应该失败。可以认为这违反了Liskov替代原则吗?

12
如果我们重写SetWidth和SetHeight方法,为什么Square从Rectangle继承会出现问题?
如果Square是Rectangle的一种类型,那么为什么Square无法从Rectangle继承?还是为什么设计不好? 我听说有人说: 如果您使Square从Rectangle派生,那么Square应该可以在您期望矩形的任何地方使用 这里有什么问题?为何Square可以在您期望矩形的任何地方使用?仅当我们创建Square对象,并且重写Square的SetWidth和SetHeight方法时,它才可用,为什么会有任何问题呢? 如果您在Rectangle基类上具有SetWidth和SetHeight方法,并且Rectangle引用指向一个Square,则SetWidth和SetHeight毫无意义,因为设置一个将更改另一个以匹配它。在这种情况下,Square无法通过带有矩形的Liskov替代测试,并且从Square继承Square的抽象是一个不好的选择。 有人可以解释以上论点吗?同样,如果我们在Square中重写SetWidth和SetHeight方法,它是否可以解决此问题? 我也听说过: 真正的问题是我们不是在建模矩形,而是在“舒适的矩​​形”上建模,即在创建后可以修改宽度或高度的矩形(并且我们仍然将其视为同一对象)。如果我们以这种方式看待矩形类,很明显,正方形不是“可接受的矩形”,因为正方形无法重塑,并且仍然是正方形(通常)。在数学上,我们看不到问题,因为在数学环境中可变性甚至都没有意义 在这里,我认为“可调整大小”是正确的术语。矩形是“可调整大小的”,正方形也是如此。我在上述论点中缺少什么吗?可以像调整任何矩形一样调整正方形的大小。

4
遵循SOLID是否会导致在技术堆栈之上编写框架?
我喜欢SOLID,并且在开发时会尽力使用和应用它。但是我不禁感到SOLID方法似乎将您的代码变成了“框架”代码-即,如果您要创建供其他开发人员使用的框架或库,则可以设计代码。 我通常练习两种编程模式-或多或少地准确创建通过需求和KISS(典型编程)提出的要求,或者创建非常通用且可重用的逻辑,服务等,从而提供其他开发人员可能需要的灵活性(框架编程) 。 如果用户确实只希望应用程序执行x和y事情,那么当您甚至都不知道这是否是一个有效的问题时,遵循SOLID并添加一堆抽象入口点是否有意义?与?如果确实添加了这些抽象的入口点,是您真的满足了用户的要求,还是在现有框架和技术堆栈之上创建了一个框架,以使将来的添加变得更加容易?在哪种情况下,您是在为客户或开发人员的利益服务? 这在Java Enterprise世界中似乎很常见,感觉好像您是在J2EE或Spring之上设计自己的框架,以便它对开发人员来说是更好的UX,而不是针对用户的UX?
70 frameworks  solid 

8
一个班级如何在不违反单一责任原则的情况下拥有多种方法
单一责任原则在维基百科上定义为 单一责任原则是一种计算机编程原则,它指出每个模块,类或功能都应对软件提供的功能的一部分负责,并且责任应完全由类封装 如果一个班级仅应承担一项职责,那么它怎么可能有不止一种方法?每种方法都不会承担不同的责任,这将意味着该类将承担多个责任。 我看到的每个展示单一责任原则的示例都使用一个只有一个方法的示例类。查看示例或使用多种方法解释类可能会有所帮助,但仍然可以认为这是一种责任。

10
为什么“最终”关键字会有用?
似乎Java拥有声明类不可继承的能力,而现在C ++也拥有。但是,根据SOLID中的“打开/关闭”原理,为什么这样做有用?对我来说,final关键字听起来像friend-是合法的,但是如果您使用它,则很可能是设计错误。请提供一些示例,其中不可派生的类将成为优秀的体系结构或设计模式的一部分。
54 java  c++  solid  final 

5
促进可测试代码的设计原则是什么?(设计可测试代码与通过测试驱动设计)
我从事的大多数项目都将开发和单元测试隔离考虑,这使得以后编写单元测试成为噩梦。我的目标是在高级和低级设计阶段本身都牢记测试。 我想知道是否存在定义明确的设计原则来促进可测试的代码。我最近了解的一个这样的原理是通过依赖注入和控制反转的依赖反转。 我读过有一种叫做SOLID的东西。我想了解是否遵循SOLID原则间接导致了易于测试的代码?如果没有,是否存在任何明确的设计原则来促进可测试的代码? 我知道有些东西称为“测试驱动开发”。虽然,我对在设计阶段本身就考虑到测试的代码设计更感兴趣,而不是通过测试来推动设计。我希望这是有道理的。 与该主题相关的另一个问题是,为了能够为每个模块编写单元测试用例,是否可以重构现有产品/项目并更改代码和设计?

5
IOC容器违反了OOP原则
IOC容器的目的是什么?合并的原因可以简化为以下内容: 当使用OOP / SOLID开发原则时,依赖注入会变得混乱。您可能具有顶层入口点,这些入口点管理着位于其自身下方的多个级别的依赖关系,并通过构造递归传递依赖关系,或者您在工厂/构建器模式和接口中有一些重复的代码,可以根据需要构建依赖关系。 没有OOP / SOLID方式可以执行此操作并拥有超级漂亮的代码。 如果上述陈述是正确的,那么IOC容器该如何做?据我所知,他们没有采用手动DI无法完成的未知技术,因此唯一的解释是IOC容器通过使用静态对象私有访问器来打破OOP / SOLID原则。 IOC容器是否在幕后打破了以下原则?这是真正的问题,因为我有很好的理解,但是感觉到其他人有更好的理解: 范围控制。范围是我对代码设计做出几乎所有决定的原因。块,本地,模块,静态/全局。范围应该非常明确,在块级别尽可能多,而在静态级别则尽可能少。您应该看到声明,实例化和生命周期的结尾。只要我明确指出,我相信该语言和GC可以管理范围。在我的研究中,我发现IOC容器将大多数或所有依赖项设置为静态,并通过幕后的一些AOP实现对其进行控制。所以没有什么是透明的。 封装。封装的目的是什么?我们为什么要保留私人会员呢?出于实际原因,因此我们的API的实现者无法通过更改状态(应由所有者类管理)来破坏实现。但是,出于安全原因,也不会发生注入超过我们的成员国并绕过验证和类控制的情况。因此,在编译之前以某种方式注入代码以允许外部访问私有成员的任何东西(模拟框架或IOC框架)都非常庞大。 单一责任原则。从表面上看,IOC容器似乎使事情更清洁。但是想象一下,如果没有帮助程序框架,您将如何完成相同的任务。您将传递带有十几个依赖项的构造函数。这并不意味着用IOC容器将其掩盖,这是一件好事!这是重构代码并遵循SRP的标志。 打开/关闭。就像SRP并非仅是类一样(我将SRP应用于单一职责范围,更不用说方法了)。打开/关闭不仅是不更改类代码的高级理论。这是一种了解程序配置并控制要更改和扩展的内容的实践。IOC容器可以部分地完全更改类的工作方式,因为: 一种。主要代码没有确定切换出依赖项,而是框架配置。 b。范围可以在不受调用成员控制的时间进行更改,而是由静态框架在外部确定。 因此,该类的配置不是真正封闭的,它会根据第三方工具的配置自行更改。 这是一个问题,是因为我不一定是所有IOC容器的大师。尽管IOC容器的想法不错,但它们似乎只是掩盖了糟糕的实现的外观。但是,为了完成外部Scope控制,私有成员访问和延迟加载,必须进行许多非平凡的可疑事情。AOP很棒,但是通过IOC容器完成AOP的方式也值得怀疑。 我可以相信C#和.NET GC可以完成我期望的工作。但是我不能再信任第三方工具来改变我的已编译代码,以执行我无法手动执行的操作的变通办法。 EG:实体框架和其他ORM创建强类型对象并将其映射到数据库实体,并提供样板功能来执行CRUD。任何人都可以建立自己的ORM,并继续手动遵循OOP / SOLID原则。但是这些框架对我们有帮助,因此我们不必每次都重新发明轮子。看来,IOC容器可以帮助我们有目的地围绕OOP / SOLID原则开展工作并加以掩盖。

7
切换到SOLID后管理和组织大量增加的课程?
在过去的几年中,我们一直在缓慢地转换为逐渐更好的书面代码,每次只需几个小步骤。我们终于开始切换到至少与SOLID类似的东西,但是我们还没有到那儿。自从进行切换以来,开发人员最大的抱怨之一就是他们无法忍受同行审查和遍历数十个文件,而以前的每个任务只需要开发人员触摸5-10个文件即可。 在开始进行转换之前,我们的体系结构非常类似于以下内容(已授予,但又增加了一个或两个数量级的文件): Solution - Business -- AccountLogic -- DocumentLogic -- UsersLogic - Entities (Database entities) - Models (Domain Models) - Repositories -- AccountRepo -- DocumentRepo -- UserRepo - ViewModels -- AccountViewModel -- DocumentViewModel -- UserViewModel - UI 从文件的角度来看,所有内容都非常线性且紧凑。显然有很多代码重复,紧密耦合和令人头疼的问题,但是,每个人都可以遍历并弄清楚。完全的新手,从来没有像以前那样打开过Visual Studio的人,就可以在几周内解决这个问题。缺乏整体文件的复杂性,对于新手开发人员和新员工来说,在不增加太多时间的情况下就开始进行贡献相对容易。但这几乎就是代码风格的任何好处都无法体现的地方。 我全心全意地支持我们为改善代码库所做的一切尝试,但是在这样的大规模范式转换中,从团队的其他成员那里得到一些回击是很普遍的。当前几个最大的症结是: 单元测试 班数 同行评审的复杂性 单元测试对于团队来说是一笔难以置信的辛苦卖点,因为他们所有人都认为这是浪费时间,并且他们能够比单个代码更快地整体测试代码。使用单元测试作为SOLID的认可在大多数情况下是徒劳的,并且在这一点上已经成为一个笑话。 上课人数可能是要克服的最大障碍。过去需要5-10个文件的任务现在可以占用70-100!尽管每个文件都有不同的用途,但文件的数量却是巨大的。团队的反应主要是吟和头部抓挠。以前,一项任务可能需要一个或两个存储库,一个或两个模型,一个逻辑层和一个控制器方法。 现在,要构建一个简单的文件保存应用程序,您需要一个类来检查文件是否已存在,一个类来编写元数据,一个类来进行抽象,DateTime.Now以便您可以投入时间进行单元测试,为每个包含逻辑的文件插入接口,包含每个类的单元测试,以及一个或多个文件以将所有内容添加到您的DI容器中。 对于中小型应用程序,SOLID非常容易出售。每个人都看到了可维护性的好处和便利。但是,他们只是没有看到SOLID在超大型应用程序中具有很好的价值主张。因此,我正在尝试寻找改善组织和管理的方法,以使我们度过不断增长的痛苦。 我以为基于最近完成的任务,可以更详细地说明文件量的示例。我被赋予一项任务,以在我们的一种较新的微服务中实现某些功能,以接收文件同步请求。收到请求后,服务将执行一系列查找和检查,最后将文档以及2个单独的数据库表保存到网络驱动器。 要将文档保存到网络驱动器,我需要一些特定的类: - …

8
LSP vs OCP / Liskov换人VS开盘关闭
我试图理解OOP的SOLID原则,并且得出的结论是LSP和OCP有一些相似之处(如果不多说的话)。 开放/封闭原则指出“软件实体(类,模块,功能等)应为扩展而开放,但为修改而封闭”。 LSP在简单的话指出,任何情况下Foo可以用的任何实例来代替Bar它源自Foo并计划将工作同样非常的方式。 我不是专业的OOP程序员,但在我看来,只有在Bar派生自LSP Foo不会更改其中任何内容而只能扩展它的情况下,LSP才是可能的。这意味着特别是程序LSP仅在OCP为true时才为true,而OCP仅在LSP为true时才为true。那意味着他们是平等的。 如果我错了纠正我。我真的很想了解这些想法。非常感谢您的回答。


7
什么时候不应用依赖倒置原则?
我目前正在尝试弄清SOLID。因此,依赖倒置原则意味着任何两个类都应该通过接口而不是直接进行通信。示例:如果class A有一个方法,该方法需要一个指向类型的对象的指针class B,则该方法实际上应在一个类型为对象的对象abstract base class of B。这对打开/关闭也有帮助。 如果我理解正确,那么我的问题是将其应用于所有类交互是一种好习惯还是应该尝试从层次上考虑? 我对此表示怀疑是因为我们为遵循这一原则付出了一些代价。说,我需要实现feature Z。经过分析,我的结论是功能Z包含的功能A,B和C。我创建了一个门面类Z,即,通过接口,使用类A,B和C。我开始编码的实施,在某些时候我意识到,任务Z实际上是由功能性A,B和D。现在,我需要取消C界面,C类原型并编写单独的D界面和类。如果没有接口,则只需要替换该类。 换句话说,要更改某些内容,我需要更改1.调用者2.接口3.声明4.实现。在python直接耦合的实现中,我只需要更改实现。

7
SOLID原则与YAGNI
SOLID原则何时会成为YAGNI? 作为程序员,我们始终在复杂性,可维护性,构建时间等之间进行权衡。在我看来,其中两项最明智的选择准则是SOLID原则和YAGNI。如果您不需要它;不要建造它,并保持干净。 现在,例如,当我观看SOLID上的dimecast系列节目时,我看到它开始时是一个非常简单的程序,然后结束时是一个非常复杂的程序(当然,在旁观者看来,复杂性也是如此),但是它仍然使我想知道:SOLID原则何时会变成您不需要的东西?所有坚实的原则都是可以使用户在以后进行更改的工作方式。但是,如果要解决的问题是一个非常简单的问题,并且是一个一次性应用程序,该怎么办?还是SOLID原则始终适用? 如评论中所述: SOLID原则 亚尼

3
编程SOLID原理
随着时间的推移,我可以理解SOLID的两个部分-“ S”和“ O”。 “ O” –我在继承和策略模式的帮助下学习了开放式封闭原则。 “ S” –我在学习ORM时学会了单一职责原则(持久性逻辑从领域对象中删除)。 以类似的方式,学习SOLID的其他部分(“ L”,“ I”和“ D”)的最佳区域/任务是什么? 参考文献 msdn-违反C#中的SOLID原则的危险 channel9-在.NET / C#中应用SOLID原理 OOPS原则(SOLID原则)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.