Unconsciously, this has been the last of the six design principles, and the completion of this article is also the completion of the sequence. Of course, in addition to learning design principles, there are many design patterns that we can understand and learn. Demeter’s Rule is the most interesting design principle I’ve ever seen. Let’s take a look.
define
Demeter’s Law: Also known as the least knowledge principle, a class should know as little as possible about other classes. This means that an object should know as little as possible about other objects and should correspond only with friends and not talk to strangers. Short for LOD.
This was a Northeastern University research project called Demeter, developed in 1987 by Ian Holland, popularized by Booch, one of the founders of UML, He later became known as The Pragmatic Programmer in his classic book.
In layman’s terms, if two software entities do not have to communicate directly, then direct calls to each other should not occur and can be forwarded by a third party.
Focus on
The purpose of Demeter’s rule is to reduce the coupling degree between classes and improve the relative independence of modules.
The one that stuck in my mind most was: Talk only to your immediate friends and not to strangers.
It the meaning of every object and other objects have coupling relationship, a relationship is called friends, such as the current object itself, the current members of the object, the current object created the object, the object of the current methods of parameter and so on, these are friends and friends of friends and the object is the relationship between “the stranger”.
Demeter asked us when designing the system, should try to reduce the interaction between objects, if do not have to communicate directly with each other between the two objects, then the two objects should not be any direct interaction, if one of the objects you need to call a method of another object, you can through third party forwarding the call. In short, it is to reduce coupling between existing objects by introducing a reasonable third party.
So how do we do that
-
In the structure design of the class, the access rights of class members should be reduced as far as possible.
-
Keep references to other objects to a minimum on references to other classes.
-
Objects must be directly related to each other in order to be related.
-
Instead of exposing the class’s attribute members, the corresponding accessors (set and GET methods) should be provided.
advantages
-
The coupling degree between classes is reduced and the relative independence of modules is improved.
-
As the affinity degree is reduced, the class reusability and system scalability are improved.
For example,
For example, buying second-hand houses can be seen everywhere in our life.
Define the Buyer class as Buyer, the Seller class as Seller, and the intermediary class as AgentComputer.
The Seller class has the method sellHouse for selling a house.
Class Seller {print() {print(" print ")}}Copy the code
The mediation class AgentComputer has a method called getHouseInfo to get the house.
// AgentComputer {func getHouseInfo(Seller: Seller) {sellHouse()}}Copy the code
The buyer through the intermediary to find the house information wantToBuyHouse.
// wantToBuyHouse() {let a = AgentComputer() let s = Seller() a.goethouseInfo (Seller: s)}}Copy the code
Output code:
var buyer = Buyer()
buyer.wantToBuyHouse()
Copy the code
Print result:
Let’s take a look at the house information
So look, indeed the seller is to get the house information. However, the lack of written code violates Demeter’s law, the buyer can have the seller’s object, if we really know the seller’s object, then why go to the intermediary, right? So the intermediary will certainly not expose the seller’s information to the buyer. It may also be considered that there is no direct relationship between the buyer and the mode of sale.
Let’s change the code so that the mediation class’s getHouseInfo method does not expose the seller.
// AgentComputer {func getHouseInfo() {let Seller = Seller() sellHouse()}}Copy the code
Then the buyer’s request changed
{func wantToBuyHouse() {let a = AgentComputer() a.goethouseinfo ()}}Copy the code
Such a change, the print result is still no problem. So what are the benefits of this
Is the buyer only friends with the intermediary, the intermediary is the method of the buyer and the seller, and the seller only friends with the intermediary? In this case, is the coupling degree lower than before? If one day the seller class changes, the buyer class doesn’t matter, right?
conclusion
From this example, can we see why we often need to re-wrap third-party libraries? In addition to extending the functionality of third-party libraries, there is another point that projects are not directly related to third parties.
For example, when we OC use the prompt box, we use the third-party library MBProgressHUD, and one day, we don’t want to use this anymore and we want to use SVProgressHUD. If the project does not have the secondary encapsulation, is it troublesome to change the place because the coupling degree is too large? If we have the secondary encapsulation class, should we change it directly there?
The six design principles can be summed up as: reduce coupling between objects and increase reusability, extensibility, and maintainability of programs.
digression
To here, six design principles finally finished, this is my first time to write a series of articles, generally speaking, just about satisfactory bar. The examples are relatively simple, and I hope to be able to understand what to write without looking at the Demo.
Github sample code is attached in accordance with international practice.
If there are shortcomings in the above statement, please take note.