观察者模式符合开闭原则
A class or module should be open for extension and closed for modification.
类或模块应打开以进行扩展,而应关闭以进行修改。
This principle was introduced by Bertrand Meyer. According to him class or module should be open for extension and closed for modification. In other words, you should be able to change the behavior of the class or module without changing the existing code.
此原理由Bertrand Meyer提出。 据他说,类或模块应该打开以进行扩展,而关闭则可以进行修改。 换句话说,您应该能够在不更改现有代码的情况下更改类或模块的行为。
What the heck?🙄 Is it really possible?🤔 This was the first word that came out of my mouth when I read it for the first time. Actually we do it oftentimes; let's decode it with an example.
这到底是什么?🙄真的有可能吗?🤔这是我第一次阅读时从我的嘴里说出的第一个单词。 实际上,我们经常这样做。 让我们用一个例子对其进行解码。
Let’s consider a typical example of a terms and conditions screen. The user will be presented with terms and conditions, he has two buttons to accept and deny it. We have to save the user’s selection inside the local storage.
让我们考虑一个条款和条件屏幕的典型示例。 将向用户显示条款和条件,他有两个按钮可以接受和拒绝。 我们必须将用户的选择保存在本地存储中。
Below is the crude way to implement the functionality. It does not follow any of the good coding practices also violates the open-closed principle.
以下是实现功能的粗略方法。 它没有遵循任何良好的编码惯例,也违反了开放-封闭原则。
A manager comes to us and says the client has a lot of problems with this application, so he has hired a consultant. They have a new idea, the client wants to provide two versions of this software. In the free version, data will be stored locally on the device and in the paid version it will be stored remotely on the server.
一位经理来找我们,说客户在此应用程序上有很多问题,因此他聘请了一名顾问。 他们有一个新主意,客户希望提供此软件的两个版本。 在免费版本中,数据将本地存储在设备上,而在付费版本中,数据将远程存储在服务器上。
Now we have to tell our manager that, we will be able to add the functionality for the store it on the remote server but we have to deploy both functionalities together. As per the current design, there is no way to separate the functionality. This called immobility.
现在我们必须告诉我们的经理,我们将能够添加将其存储在远程服务器上的功能,但是我们必须将这两个功能一起部署。 根据当前的设计,无法分离功能。 这称为固定性。
When we add the functionality for storing data on a remote server the UI and business logic will get recompiled, this is rigidity.
当我们添加了用于在远程服务器上存储数据的功能时,UI和业务逻辑将被重新编译,这就是刚性。
Also, we have to add a check whether the account is paid or free and accordingly execute the code for saving the data. There will be several such conditions throughout the codebase making the code fragile.
此外,我们还必须添加一个检查帐户是付费还是免费的帐户,然后执行代码以保存数据。 整个代码库中都会有几种这样的条件,使代码易碎。
如何应用开闭原则? (How to apply the Open-Closed principle?)
Let’s modify this code to avoid these bad symptoms and achieve the objective of paid and free accounts. Let's segregate the class into two modules, first will be responsible for UI related stuff and second will deal with data storage options.
让我们修改此代码以避免这些不良症状,并实现付费和免费帐户的目标。 让我们将类分为两个模块,第一个将负责与UI相关的工作,第二个将处理数据存储选项。
We will continue using activity for UI related stuff. We have also created a presenter that will segregate the business logic from our UI.
我们将继续使用与UI相关的活动。 我们还创建了一个演示者,该演示者将业务逻辑与我们的UI隔离。
These two classes will be part of our UI module. In the same module, we will be defining the TermsAndConditionsRepository interface which has a method for updating terms and conditions preference. TermsAndConditionsPresenter will always depend on this abstract interface instead of the actual implementation.
这两个类将成为我们UI模块的一部分。 在同一模块中,我们将定义TermsAndConditionsRepository接口,该接口具有一种更新条款和条件首选项的方法。 TermsAndConditionsPresenter将始终依赖于此抽象接口,而不是实际的实现。
Now in the second module, we will be having an implementation of the above interface that will store the data in local storage. I am calling it as TermsAndConditionsLocalRepository.
现在在第二个模块中,我们将实现上述接口的实现,该接口将数据存储在本地存储中。 我称它为TermsAndConditionsLocalRepository。
After refactoring this code now we have to make changes to store data on a remote server. Now we will create a new class in another module called TermsAndConditionsRemoteRepository, which will extend the TermsAndConditionsRepository and deal with communication with the server. I am using the Retrofit library for this purpose.
重构此代码后,我们现在必须进行更改以将数据存储在远程服务器上。 现在,我们将在另一个名为TermsAndConditionsRemoteRepository的模块中创建一个新类,该模块将扩展TermsAndConditionsRepository并处理与服务器的通信。 我正在为此目的使用Retrofit库。
As we have added the TermsAndConditionsRemoteRepository the code inside TermsAndConditionsPresenter and TermsAndConditionsActivity will not be recompiled so we get rid of rigidity.
当我们添加了TermsAndConditionsRemoteRepository后,不会重新编译TermsAndConditionsPresenter和TermsAndConditionsActivity内部的代码,因此我们摆脱了僵化。
There are no if-else conditions as we have separate versions of the application as requested by the client. This will get rid of fragility.
没有if-else条件,因为我们有客户要求的单独版本的应用程序。 这将摆脱脆弱性。
We will compose the application either with local storage or remote server. This will get rid of immobility.
我们将使用本地存储或远程服务器来组合应用程序。 这将摆脱固定性。
该原则在哪里适用? (Where to apply this principle?)
This principle will help us to protect against the changes. That does not mean we have to apply it to each and every class. Practically it is almost impossible to do it considering the time and effort it will take.
这一原则将有助于我们防止变化。 这并不意味着我们必须将其应用于每个班级。 考虑到将花费的时间和精力,实际上几乎是不可能的。
Instead, we should identify the points where an application is prone to changes. Apply this principle only at those points. There are two ways to identify these changes, one is from your previous experience another is from the user’s feedback. By following the Agile methods we will be able to get continuous feedback from the user and with it, we will be able to apply this wherever needed. This is an ongoing process and will evolve with time.
相反,我们应该确定应用程序易于更改的地方。 仅在这些情况下应用此原则。 有两种方法可以识别这些更改,一种是根据您以前的经验,另一种是根据用户的反馈。 通过遵循敏捷方法,我们将能够从用户那里获得持续的反馈,并且有了它,我们将能够在需要的任何地方应用它。 这是一个持续的过程,并且会随着时间而发展。
翻译自: https://medium.com/@gaurang.shaha_6814/open-closed-principle-5100632df310
观察者模式符合开闭原则