Questions tagged «solid»

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

6
通过逆转关系可以解决圆椭圆问题吗?
具有CircleextendEllipse违反了Liskov替换原理,因为它修改了后置条件:即,可以独立设置X和Y来绘制椭圆,但是对于圆,X必须始终等于Y。 但是,不是因为Circle是Ellipse的子类型引起的问题吗?我们不能扭转这种关系吗? 因此,Circle是超类型-它只有一个方法setRadius。 然后,椭圆通过添加setX和扩展Circle setY。调用setRadiusEllipse将同时设置X和Y-意味着保留setRadius的后置条件,但是现在您可以通过扩展接口独立设置X和Y。

5
微型重构代码以提高质量是否有用,还是只是“移动代码”而没有太多好处?
例 我遇到了在一个地方完成所有工作的整体代码-从数据库加载数据,显示HTML标记,充当路由器/控制器/动作。我开始应用SRP将数据库代码移动到其自己的文件中,从而为事物提供了更好的命名,而且看起来都不错,但是随后我开始怀疑为什么要这样做。 为什么要重构?什么目的?它没用吗?有什么好处?请注意,我基本上保留了整体文件,但只重构了与需要进行某些工作的区域相关的较小部分。 原始代码: 举一个具体的例子,我遇到了以下代码片段-它通过已知的产品ID或用户选择的版本ID加载产品规格: if ($verid) $sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid); else $sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ; $result1 = query($sql1); $row1 = fetch_array($result1); /* html markup follows */ 重构: 由于我正在做一些工作,要求我在代码的此特定部分中进行更改,因此我将其更改为使用存储库模式,并将其升级为使用面向对象的MySQL工具: //some implementation details omitted …


5
重载了开放/封闭原则的例子吗?
维基百科说 “软件实体(类,模块,功能等)应打开以进行扩展,但应关闭以进行修改” 函数一词引起了我的注意,现在我想知道是否可以假定为方法创建重载可以视为“打开/关闭”原理的示例吗? 让我解释一个例子。考虑一下您的服务层中有一个方法,该方法在将近1000个地方中使用。该方法获取userId并确定用户是否为admin: bool IsAdmin(userId) 现在考虑在某个地方,有必要根据用户名而不是userId来确定用户是否为admin。如果我们更改上述方法的签名,那么我们已经在1000个地方破坏了代码(功能应禁止修改)。因此,我们可以创建一个重载来获取用户名,基于用户名找到userId以及原始方法: public bool IsAdmin(string username) { int userId = UserManager.GetUser(username).Id; return IsAdmin(userId); } 这样,我们通过为其创建重载扩展了功能(功能应可扩展)。 它是一个开放/封闭原则的例子吗?

4
如何在C#中的接口中指定前提条件(LSP)?
假设我们有以下界面- interface IDatabase { string ConnectionString{get;set;} void ExecuteNoQuery(string sql); void ExecuteNoQuery(string[] sql); //Various other methods all requiring ConnectionString to be set } 前提条件是必须先设置/初始化ConnectionString,然后才能运行任何方法。 如果IDatabase是抽象类或具体类,则可以通过构造函数传递connectionString来某种程度地达到此前提条件- abstract class Database { public string ConnectionString{get;set;} public Database(string connectionString){ ConnectionString = connectionString;} public void ExecuteNoQuery(string sql); public void ExecuteNoQuery(string[] sql); //Various other methods all requiring …

9
SOLID与静态方法
这是我经常遇到的一个问题:假设有一个具有Product类的网上商店项目。我想添加一个功能,允许用户对产品发表评论。所以我有一个Review类,它引用一个产品。现在,我需要一种列出所有产品评论的方法。有两种可能性: (一种) public class Product { ... public Collection<Review> getReviews() {...} } (B) public class Review { ... static public Collection<Review> forProduct( Product product ) {...} } 通过查看代码,我将选择(A):它不是静态的,并且不需要参数。但是,我认为(A)违反了单一责任原则(SRP)和开放式封闭原则(OCP),而(B)没有违反: (SRP)当我想更改收集产品评论的方式时,我必须更改产品类。但是更改产品类的原因应该只有一个。那当然不是评论。如果我在产品中打包了与产品有关的所有功能,它将很快崩溃。 (OCP)我必须更改Product类以使用此功能对其进行扩展。我认为这违反了原则的“为变革而封闭”部分。在我收到客户的要求以实施评论之前,我认为产品已完成,然后“关闭”。 更重要的是:遵循SOLID原则,还是拥有更简单的界面? 还是我在这里做错了什么? 结果 哇,谢谢您的所有精彩回答!很难选择一个作为官方答案。 让我总结一下答案中的主要论点: 赞成(A):OCP不是法律,代码的可读性也很重要。 亲(A):实体关系应该是可导航的。两个类都可能知道这种关系。 pro(A)+(B):同时执行并将(A)中的任务委派给(B),这样就不太可能再次更改产品。 pro(C):将finder方法放在非静态的第三类(服务)中。 反对(B):阻止测试中的嘲笑。 我的大学在工作中还提供了一些其他功能: 亲(B):我们的ORM框架可以自动生成(B)的代码。 赞成(A):由于我们ORM框架的技术原因,在某些情况下,有必要独立于发现者去向而更改“封闭”实体。因此,无论如何,我将始终无法坚持使用SOLID。 对比(C):大惊小怪;-) 结论 我在当前项目中同时使用(A)+(B)和委派。但是,在面向服务的环境中,我将选择(C)。

4
对设计模式和OOP实践的思考如何在动态和弱类型语言中发生变化?
这些方面已经有了一个相当有用的问题(“ 非OOP设计模式? ”),但是我对于刚开始使用动态和弱类型语言的人的过渡观点感到更加好奇。 那就是:假设我已经使用C ++,C#或Java进行编程多年,并从GoF设计模式,Fowler 企业应用程序体系结构模式,SOLID原理等方面吸取了很多智慧。 m涉猎Ruby,Python,JavaScript等,并想知道我的知识如何应用。大概在很多情况下我都可以进行直接翻译,但是几乎可以肯定的是,这并不能充分利用我的新设置。仅仅靠鸭子打字就可以改变我很多基于界面的思想。 什么保持不变?有什么变化?是否有新手应该知道的诸如SOLID之类的指导原则或动态语言新手应该知道的规范模式(也许是全新的)?

3
接口隔离原则是否适用于具体方法?
由于接口隔离原则表明,不应强迫任何客户端依赖其不使用的方法,因此客户端不应为其接口方法实现空方法,否则应将此接口方法放入另一个接口。 但是具体方法呢?我应该分开不是每个客户都会使用的方法吗?考虑以下类别: public class Car{ .... public boolean isQualityPass(){ ... } public int getTax(){ ... } public int getCost(){ ... } } public class CarShop{ ... public int getCarPrice(int carId){ Car car=carList[carId]; int price=car.getTax() + car.getCost()... (some formula); return price; } } 在上面的代码中,CarShop根本不在Car中使用方法isQualityPass(),我应该将isQualityPass()分离到一个新类中: public class CheckCarQualityPass{ public boolean isQualityPass(Car car){ …

2
遵循SRP时,应如何处理验证和保存实体?
最近,我一直在阅读Clean Code和各种有关SOLID的在线文章,而我阅读的内容越多,我感觉自己一无所知。 假设我正在使用ASP.NET MVC 3构建Web应用程序。假设我有一个类似这样UsersController的Create操作: public class UsersController : Controller { public ActionResult Create(CreateUserViewModel viewModel) { } } 在这种操作方法中,如果输入的数据有效,我想将用户保存到数据库中。 现在,根据“单一责任原则”,对象应具有单一责任,并且该责任应由类完全封装。它的所有服务都应严格地与这一责任保持一致。由于验证和保存到数据库是两个单独的职责,我想我应该创建一个单独的类来像这样处理它们: public class UsersController : Controller { private ICreateUserValidator validator; private IUserService service; public UsersController(ICreateUserValidator validator, IUserService service) { this.validator = validator; this.service= service; } public ActionResult Create(CreateUserViewModel viewModel) { ValidationResult …

3
使用SOLID原则时,开发人员的可发现性是否成问题?
我从事一系列商务应用程序,在这些应用程序中,所有其他开发人员都习惯于使用基本的CRUD应用程序,或者只专注于创建漂亮/功能强大的界面,因此,我得到了很多帮助。 “通过我们使用的方式,员工将拥有您可能对员工所做的所有事情。” 这是真的。那个“班级”有成千上万的代码行,您在那里可以与一名员工一起做的任何事情。甚至更糟的是,有一张员工数据表,每个开发人员都想出了如何在事件处理程序中做他们想做的事情。 关于这种方法的所有坏事都是对的,但是至少使用雇员的开发人员可以在不查阅其他文件的情况下,弄清楚如何使雇员参加健康计划,加薪,解雇,雇用,调动等。经理和其他所有主要想法。或者,如果他们使用员工其他需要的数据表,则可以做他们想要的事情。 是的,有很多重复的代码。是的,这是非常脆弱的代码。是的,测试比必要的困难得多。是的,不断变化的功能导致恐惧,而复制粘贴由于这种方法是很自然的。 但是他们至少可以通过创建一个类来发现可用的东西,或者他们可以做他们需要做的事情而不必了解接口,抽象类,具体类等之间的区别。他们不必搜索任何东西由intellisense返回的方法,或知道数据所在的表。 我已经用谷歌搜索/搜索甚至是yahoo!d,但是我没有发现任何对此问题的认可。 因此,也许没有问题,而我只是想念一些东西。我竭尽全力试图找到一个解决方案,使不执行实际行为/设计的开发人员可以轻松地发现如何做某事,而不必引用任何外部文档或扫描各个组件/中的类名。项目,寻找听起来可行的方案。 我唯一能想到的就是这些,因为缺少更好的名称,“ Content Class Table”不执行任何操作以返回实际的类(实际上,大多数是接口,但它们不是了解其他开发人员可以用来执行所需实际任务的区别甚至是关心。仍然会出现真正的大类,但其中几乎没有行为。 有没有更好的方法不需要对SOLID的实际实现发生在中间层的深入了解? 基本上,我要问的是有一种方法可以允许CRUD类型的开发人员继续在非常复杂的系统中成为CRUD开发人员。
10 solid  crud 


7
规避巫师和战士中的规则
在这一系列博客文章中,Eric Lippert使用向导和战士作为示例描述了面向对象设计中的问题,其中: abstract class Weapon { } sealed class Staff : Weapon { } sealed class Sword : Weapon { } abstract class Player { public Weapon Weapon { get; set; } } sealed class Wizard : Player { } sealed class Warrior : Player { } 然后添加一些规则: 战士只能使用剑。 向导只能使用人员。 …

2
接口隔离原理:如果接口存在大量重叠该怎么办?
摘自敏捷软件开发,原理,模式和实践:Pearson新国际版: 有时,由不同客户端组调用的方法会重叠。如果重叠很小,则组的接口应保持分离。公用功能应在所有重叠的接口中声明。服务器类将从每个接口继承通用功能,但仅实现一次。 鲍伯叔叔,谈论有微小重叠的情况。 如果出现大量重叠该怎么办? 说我们有 Class UiInterface1; Class UiInterface2; Class UiInterface3; Class UiIterface : public UiInterface1, public UiInterface2, public UiInterface3{}; 如果UiInterface1和之间有大量重叠,该UiInterface2怎么办?

2
是否有“只问您需要”的界面原则?
我已经成长为使用一种设计和使用接口的原理,该原理基本上说:“只问您需要什么”。 例如,如果我有一堆可以删除的类型,我将创建一个Deletable接口: interface Deletable { void delete(); } 然后,我可以编写一个通用类: class Deleter<T extends Deletable> { void delete(T t) { t.delete(); } } 在代码的其他地方,我总是要求最小的责任来满足客户代码的需求。因此,如果我只需要删除一个File,我仍然会要求一个Deletable,而不是一个File。 这个原则是常识并且已经有公认的名称吗?有争议吗?在教科书中讨论过吗?

6
最终现场采访的“雇用”和诚实的“差不多”之间有什么区别?[关闭]
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 6年前关闭。 因此,我最近接受了Google和Amazon的现场采访,并收到有礼貌的拒​​绝信,让我知道我已经接近了,但对于他们正在寻找的技能并不完全正确。 我已经完成了所有面试的最后一轮(除了一些我从小无趣的职位中获得的一些实习机会),但到目前为止,一天中有5到8个面试给了我足够的时间我的错误加起来足以使我无法参加比赛。 我知道我至少在编码问题和其他一般技术问题上做得很好,尽管我在设计OOP之类的纸牌游戏或停车库方面做得很糟糕(但是我深陷于一个物体中,并用尽了我的全部时间, (虽然范围更广)和我的编码答案(尽管它们总体上是有效的)并没有遗漏一些错误/边缘情况(例如,输入节点实际上可以作为答案而不是需要区分的情况)。我也没问题说“我不知道”,但是也许我在闲逛,需要对我认为可以回答的问题说出来,但是不能给...一个清晰的答案。 那么,是什么因素使您从善而不是“ Hire”中脱颖而出? 您对所寻找的东西或已知的东西有什么建议吗?
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.