张店网络推广公司,seo技术是什么,网站设计的方法,小程序商城开发华网天下优秀不用说#xff0c;每个对象都需要先创建才能使用。 无论我们是在谈论域#xff0c;框架#xff0c;库还是任何其他类型的类#xff0c;都没有关系。 当您的代码是面向对象的时#xff0c;这些类仅是对象的定义。 在创建对象之前#xff0c;不能使用它们。 在谈论对象的初… 不用说每个对象都需要先创建才能使用。 无论我们是在谈论域框架库还是任何其他类型的类都没有关系。 当您的代码是面向对象的时这些类仅是对象的定义。 在创建对象之前不能使用它们。 在谈论对象的初始化时我们经常需要考虑依赖关系。 您将如何注入它们 您会使用构造函数还是二传手 让我来帮助您做出正确的决定。 很久以前.. ……需要处理一些事件。 为此我们必须首先从存储库中检索必要的数据然后将其传递给触发器该触发器负责根据给定的数据触发适当的操作。 在实现过程中我们创建了以下类 public class SomeHandler {public SomeHandler(Repository repository, Trigger trigger) {// some code}public void handle(SomeEvent event) {// some code}
} 事情总是在变化。 我们的客户告诉我们他们有时会需要存储从存储库中检索到的一些信息然后才能采取适当的措施。 他们需要此数据用于统计目的和进一步分析。 更改后这是我们班级的样子 public class SomeHandler {public SomeHandler(Repository repository, Trigger trigger) {// some code}public SomeHandler(Repository repository, Trigger trigger, SnapshotTaker snapshotTaker) {// some code}public void handle(SomeEvent event) {// some code}
} 又过了一个月客户提出了另一个要求。 他们希望有可能在触发事件后立即启用通知。 对于某些紧急事件这对于他们来说是必要的。 他们希望具有更高的透明度。 好的现在我们可以启用两件事 public class SomeHandler {public SomeHandler(Repository repository, Trigger trigger) {// some code}public SomeHandler(Repository repository, Trigger trigger, SnapshotTaker snapshotTaker) {// some code}public SomeHandler(Repository repository, Trigger trigger, Notifier notifier) {// some code}public SomeHandler(Repository repository, Trigger trigger, SnapshotTaker snapshotTaker, Notifier notifier) {// some code}public void handle(SomeEvent event) {// some code}
} 代码看起来不错不是吗 好的这是一个反问。 让我们做些事情。 构造器与否 在上面的示例中我们有四个构造函数的类。 为什么那么多 由于客户需求的变化。 这很好。 一个应用程序应该满足客户的需求。 问题出在哪里 问题在于类的设计。 为什么我们有这么多构造函数 由于某些依赖项是可选的因此它们的存在取决于外部条件。 我们需要这么多构造函数吗 在回答这个问题之前最好先问一个不同的问题 构造函数的目的是什么 我们应该创建一个处于有效状态的对象。 如果需要做更多的事情来使对象可用我们就不应创建实例。 这就是为什么所有必需的依赖项都应放在构造函数中的原因 。 另一方面 我们应仅将所需的依赖项放在构造函数中 。 构造函数不是放置任何可选内容的地方。 如果某些东西是可选的则意味着我们不需要它来创建有效的对象。 如果我们想使用其他很好的依赖项则应该以其他方式注入它们。 这就是二传手的角色。 我们没有被迫调用setter方法。 我们可能有需要但这不是必需的。 当依赖项为选项时应使用setter 。 那么我们需要那么多构造函数吗 让代码作为答案 public class SomeHandler {public SomeHandler(Repository repository, Trigger trigger) {// some code}public void setSnapshotTaker(SnapshotTaker snapshotTaker) {// some code}public void setNotifier(Notifier notifier) {// some code}public void handle(SomeEvent event) {// some code}
} 更少的代码更具描述性。 从第一刻起您就知道需要什么以及可以使用什么。 塞特犬 我不喜欢二传手。 为什么 因为这些方法以某种方式破坏了封装 。 但是我们可以用什么代替二传手 在给定的示例中可以代替使用什么 好吧我们不会避免使用这些方法。 或更确切地说我们需要它们的功能。 需要让客户启用该功能。 在给定的示例中因为需要变量所以需要保留它们。 但是我们总是可以使代码更好。 与域更多相关。 怎么样 我们只需要显示与域的这种关系 public class SomeHandler {public SomeHandler(Repository repository, Trigger trigger) {// some code}public void enable(SnapshotTaker snapshotTaker) {// some code}public void enable(Notifier notifier) {// some code}public void handle(SomeEvent event) {// some code}
} 我写道我不喜欢setter因为它们的中断封装但这不仅与方法的功能本身有关。 使用诸如setX之类的方法的另一个问题是即使它们的名称也是面向实现的。 有时setter功能是必需的。 但是请记住以一种显示域含义的方式来命名方法。 太多选择 有时太多的选择也会带来问题。 这可能表明您违反了“ 单一责任原则” 。 如果选择太多可能意味着责任过多值得重新考虑当前的解决方案。 每当在类的代码中添加另一个可选部分时都要非常小心。 也许这堂课做得太多了 字尾 希望您觉得这篇文章有用。 现在您应该知道应该只在构造函数中放置必需的依赖项。 任何可选的依赖项都需要其他命名良好的方法。 下一步是什么 我们去创建一些对象 翻译自: https://www.javacodegeeks.com/2016/02/constructor-or-setter.html