Questions tagged «single-responsibility»

单一责任原则指出,系统中的每个模块都应负责单个功能或功能,或聚合功能的集合。另一种通用的表达方式是说每个模块应该只有一个更改的理由。

6
在实现旁边记录是否违反SRP?
在考虑敏捷软件开发和所有原理(SRP,OCP等)时,我问自己如何对待日志记录。 在实现旁边记录是否违反SRP? 我会说,yes因为该实现也应该能够运行而无需登录。那么如何更好地实现日志记录呢?我检查了一些模式,得出的结论是,最好不要以用户定义的方式违反原则,而是使用已知违反原则的任何模式的最佳方式是使用装饰器模式。 假设我们有一堆完全没有违反SRP的组件,然后我们想要添加日志记录。 成分A 组件B使用A 我们想要记录A,因此我们创建了另一个装饰有A的组件D,都实现了接口I。 接口我 组件L(系统的日志记录组件) 组件A实现I 组件D实现I,修饰/使用A,使用L进行日志记录 组件B使用I 优点:-我可以不使用日志就使用A-测试A意味着我不需要任何日志模拟-测试更简单 缺点:-更多组件和更多测试 我知道这似乎是另一个公开讨论的问题,但我实际上想知道是否有人使用的记录策略比装饰器或SRP违规更好。作为默认NullLogger的静态单例记录器又如何呢?如果需要syslog-logging,则在运行时更改实现对象?

6
多重继承是否违反单一责任原则?
如果您有一个从两个不同的类继承的类,这是否意味着您的子类自动(至少)自动做2件事,每个超类都做一件? 我相信,如果您有多个接口继承,也没有什么区别。 编辑:明确地说,我认为如果子类化多个类违反了SRP,则实现多个(非标记或基本接口(例如,可比较)接口)也违反了SRP。

4
单一责任原则是否适用于职能?
根据Robert C. Martin所说,SRP指出: 改变班级的理由不应该只有一个以上。 但是,在他的《清洁代码》第3章:函数中,他显示了以下代码块: public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeType(e.type); } } 然后指出: 此功能有几个问题。首先,它很大,并且当添加新的雇员类型时,它会增长。其次,它显然做的不止一件事。第三,它违反了“单一责任原则”(SRP),因为有多个原因使其改变。[强调我的] 首先,我认为SRP是为类定义的,但事实证明它也适用于函数。其次,该功能有多个原因需要改变吗?我只能看到它随着Employee的变化而改变。

5
SRP(单一责任原则)是客观的吗?
考虑两个想要设计“吸引用户”设计的UI设计师。“吸引用户”是一个不客观的概念,仅存在于设计师的脑海中。因此,设计师A可以选择红色,而设计师B可以选择蓝色。设计器A创建的布局与设计器B完全不同,依此类推。 我读到有关SRP(单一责任原则)的知识,我理解的是一种主观分析或对职责的分解,这些职责可能因OO设计者而异。我对吗?换句话说,是否有可能有两个优秀的面向对象的分析器和设计人员针对一个基于SRP原理的系统提出两种不同的设计?

5
MVC:控制器是否违反了单一责任原则?
单一责任原则指出“班级应该有一个改变的理由”。 在MVC模式中,Controller的工作是在视图和模型之间进行中介。它为View提供了一个界面,以报告用户在GUI上进行的操作(例如,允许View调用controller.specificButtonPressed()),并且能够在Model上调用适当的方法,以操纵其数据或调用其操作(例如model.doSomething()) 。 这意味着: 控制器需要了解GUI,以便为“视图”提供合适的界面来报告用户操作。 它还需要了解模型中的逻辑,以便能够在模型上调用适当的方法。 这意味着有两个更改的原因:GUI的更改和商务逻辑的更改。 如果GUI发生更改,例如添加了新按钮,则控制器可能需要添加新方法,以允许视图报告用户对该按钮的按下情况。 而且,如果模型中的业务逻辑发生了变化,则控制器可能必须进行更改才能在模型上调用正确的方法。 因此,控制器有两个可能的变化原因。它会破坏SRP吗?

7
我应该重构主要由一个正则表达式组成的大型函数吗?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我刚刚编写了一个跨越约100行的函数。听到这个消息,您可能很想告诉我有关单一责任的事,并敦促我进行重构。这也是我的直觉,但这是问题所在:函数做一件事。它执行复杂的字符串操作,并且函数主体主要由一个详细的正则表达式组成,分为许多行,并记录在案。如果我将正则表达式分解为多个功能,我会感觉实际上会失去可读性,因为我正在有效地切换语言,并且无法利用正则表达式提供的某些功能。现在是我的问题: 在使用正则表达式进行字符串操作时,大型函数体是否仍然是反模式?似乎命名捕获组的作用与功能非常相似。顺便说一下,我对通过正则表达式的每个流进行测试。

4
单一职责模式对班级应该有多具体?
例如,假设您有一个控制台游戏程序,该程序具有往返于控制台的各种输入/输出方法。难道是聪明的,让他们在一个单一inputOutput类或把它们分解到更具体的类,如startMenuIO,inGameIO,playerIO,gameBoardIO,等使得每个班大约有1-5的方法呢? 同时,如果最好将它们分解,将它们放置在IO命名空间中是否明智,从而使它们更冗长,例如:IO.inGame等?

4
大班单责任
我有一个2500行Character类: 跟踪游戏中角色的内部状态。 加载并保持该状态。 处理大约30个传入命令(通常=将它们转发到Game,但是一些只读命令会立即得到响应)。 从Game正在采取的行动和他人的相关行动中收到约80个电话。 在我看来,这Character只有一个责任:管理角色的状态,在传入的命令和游戏之间进行调解。 还有其他一些职责已经分解: Character具有Outgoing调用的,以为客户端应用程序生成传出更新。 Character有一个Timer跟踪下一次允许它做某事的时间。对此验证了传入的命令。 所以我的问题是,在SRP和类似原则下拥有如此大的课程是否可以接受?是否有任何最佳实践来减轻它的麻烦(例如,将方法拆分为单独的文件)?还是我错过了一些东西,真的有很好的方法将其拆分吗?我意识到这是非常主观的,希望获得其他人的反馈。 这是一个示例: class Character(object): def __init__(self): self.game = None self.health = 1000 self.successful_attacks = 0 self.points = 0 self.timer = Timer() self.outgoing = Outgoing(self) def load(self, db, id): self.health, self.successful_attacks, self.points = db.load_character_data(id) def save(self, db, id): db.save_character_data(self, health, self.successful_attacks, self.points) …


5
域实体是否违反单一责任原则?
实体的单一责任(改变的原因)应该是唯一地标识自己,换句话说,是可以发现其责任的。 埃里克·埃文(Eric Evan)的DDD书,第16页。93: 实体的最基本责任是建立连续性,使行为清晰可预测。如果他们备用,他们会做到最好。与其着重于属性甚至行为,不如将实体对象的定义简化为最固有的特征,尤其是那些识别该特征或通常用于查找或匹配该特征的特征。仅添加对于该行为所需的概念和属性必不可少的行为。 除此之外,还希望将行为和属性删除到与核心Entity相关联的其他对象中。除了身份问题外,实体还倾向于通过协调其拥有的对象的操作来履行其职责。 1。 ...将ENTITY对象的定义简化为最固有的特征,尤其是那些识别它或通常用于查找或匹配它的特征。仅添加对该概念必不可少的行为... 为实体分配一个唯一的ID后,它的身份就会建立,因此我认为这样的实体不需要任何行为就能维持其身份或帮助其识别自己。因此,我不明白作者用“ 对于概念必不可少的行为 ” 指的是什么行为(除了find和match 操作之外)? 2。 ...将ENTITY对象的定义简化为最固有的特征,尤其是那些识别它或通常用于查找或匹配它的特征。...除此之外,还希望将行为和属性删除到与核心ENTITY相关的其他对象中。 因此,任何无助于识别实体的行为,但我们仍将其表征为该实体的固有特征(即吠叫是狗固有的,飞行是飞机固有的,产卵是鸟类固有的.. ),应该放入与该实体关联的其他对象中(例如:我们应该将吠叫行为放入与dog实体关联的对象中)? 3。 除此之外,还希望将行为和属性删除到与核心ENTITY相关联的其他对象中。 一)MyEntity代表的职责A_resp和B_resp对象a,并b分别。 即使大多数的A_resp和B_resp工作是由做a和b的情况下,客户端仍担任A_resp并B_resp通过MyEntity,这意味着,从客户的角度来看,这两个职责属于MyEntity。这样,难道这不是意味着MyEntity也有A_resp和B_resp责任,因此违反了SRP? b)即使我们假设A_resp并且B_resp不属于MyEntity,MyEntity仍然有责任AB_resp协调对象a和的操作b。因此,不MyEntity违反SRP,因为它至少具有两项职责 –唯一标识自己,以及AB_resp? class MyEntity { private A a = ... private B b = ... public A GetA() { ... } public B GetB() { ... } /* coordinates operations …

3
当调用成本很高时,通过Python中的单一职责原则(SRP)进行工作
一些基点: 由于其解释性质,Python方法调用是“昂贵的”。从理论上讲,如果您的代码足够简单,那么分解Python代码除了会提高可读性和重用性之外,还会带来负面影响(这对开发人员而言是一大收获,对用户而言却不是很多)。 单一责任原则(SRP)可使代码保持可读性,易于测试和维护。 该项目具有特殊的背景,我们需要可读的代码,测试和时间性能。 例如,像这样的调用多个方法(x4)的代码比随后的仅一个方法慢。 from operator import add class Vector: def __init__(self,list_of_3): self.coordinates = list_of_3 def move(self,movement): self.coordinates = list( map(add, self.coordinates, movement)) return self.coordinates def revert(self): self.coordinates = self.coordinates[::-1] return self.coordinates def get_coordinates(self): return self.coordinates ## Operation with one vector vec3 = Vector([1,2,3]) vec3.move([1,1,1]) vec3.revert() vec3.get_coordinates() 与此相比: from …

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
如何避免在管理缓存的类中违反SRP?
注意:代码示例是用c#编写的,但这无关紧要。我将c#用作标签,因为找不到更合适的标签。这是关于代码结构的。 我正在阅读Clean Code,并试图成为一个更好的程序员。 我经常发现自己难以遵循“单一责任原则”(类和功能只能做一件事),尤其是在功能方面。也许我的问题是“一件事”的定义不明确,但仍然... 一个例子:我在数据库中有一个Fluffies列表。我们不在乎什么是蓬松。我想上课恢复蓬松。但是,蓬松可以根据某些逻辑进行更改。根据某些逻辑,此类将从缓存中返回数据或从数据库中获取最新数据。我们可以说它管理蓬松,这是一回事。为了简单起见,假设加载的数据可以使用一个小时,然后必须重新加载。 class FluffiesManager { private Fluffies m_Cache; private DateTime m_NextReload = DateTime.MinValue; // ... public Fluffies GetFluffies() { if (NeedsReload()) LoadFluffies(); return m_Cache; } private NeedsReload() { return (m_NextReload < DateTime.Now); } private void LoadFluffies() { GetFluffiesFromDb(); UpdateNextLoad(); } private void UpdateNextLoad() { m_NextReload = DatTime.Now …

3
IValidaableObject与单一责任
我喜欢MVC的可扩展性,它允许视图模型实现IValidatableObject,并添加自定义验证。 我尝试使我的控制器保持精简,使此代码成为唯一的验证逻辑: if (!ModelState.IsValid) return View(loginViewModel); 例如,登录视图模型实现IValidatableObject,通过构造函数注入获取ILoginValidator对象: public interface ILoginValidator { bool UserExists(string email); bool IsLoginValid(string userName, string password); } 似乎在视图模型中注入实例的Ninject并不是真正的惯例,甚至可能是反模式? 这是一个好方法吗?有更好的吗?

5
代码重复与多负责任的方法
我尝试遵循“单一职责原则”(SRP),并且也省略代码重复。但是,通常在某些地方存在代码重复,这些代码重复不过是调用的代码块,这些代码块无法将其提取到至少有意义的命名方法中: DoAction1(); DoAction2(); if (value) DoAction3(); DoAction4(); 将此类代码提取到方法中的最佳方法是什么?如何命名?

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.