In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "the introduction of Demeter rule and Richter substitution principle in the seven design principles of java design pattern". In daily operation, it is believed that many people have doubts about the introduction of Dimitt rule and Richter substitution principle in the seven design principles of java design pattern. The editor consulted all kinds of materials and sorted out simple and useful operation methods. I hope it will be helpful for you to answer the doubts about the introduction of Dimitt's rule and Richter replacement principle in the seven design principles of java design pattern. Next, please follow the editor to study!
Overview
A brief introduction to the seven design principles:
Open-close principle: is the core of all object-oriented design, open to extensions, closed to modifications
Dependency inversion principle: programming for interfaces, relying on abstraction rather than concrete
Single responsibility principle: an interface is responsible for only one thing, and there can only be one reason for class change.
Interface isolation principle: use multiple specialized interfaces instead of one master interface
Dimitt rule (least known principle): only communicate with friends (member variables, method input and output parameters), do not talk to strangers, control access modifiers
Richter substitution principle: subclasses can expand the functions of the parent class, but can not change the original function of the parent class
Principle of synthetic reuse: try to use object composition (has-a) / aggregation (contanis-a) instead of inheritance relationship to achieve the purpose of software reuse.
Definition of Demeter's rule
The Law of Demeter LoD principle means that an object should have the least understanding of other objects, also known as the least knowing principle (Least Knowledge Principle,LKP), to minimize the coupling between classes.
The Dimitt principle mainly emphasizes only communicating with friends and not talking to strangers. The class that appears in the member variable, the input of the method, and the output parameter can all be called the member friend class, while the class that appears inside the method body does not belong to the friend class.
Example
Now to design a permissions system, Boss needs to look at the number of courses currently published online. At this time, Boss needs to find TeamLeader to do statistics, and TeamLeader will tell Boss the statistical results. Next, let's look at the code:
Course class:
/ * * @ author eamon.zhang * @ date 2019-09-26 9:17 * / public class Course {}
TeamLeader class:
/ * * @ author eamon.zhang * @ date 2019-09-26 9:17 * / public class TeamLeader {public void checkNumberOfCourses (List courseList) {System.out.println ("the number of courses published so far is:" + courseList.size ());}}
Boss class:
/ * * @ author eamon.zhang * @ date 2019-09-26 9:17 * / public class Boss {public void commandCheckNumber (TeamLeader teamLeader) {/ / simulate Boss page by page, TeamLeader real-time statistics List courseList = new ArrayList (); for (int I = 0; I)
< 20; i++) { courseList.add(new Course()); } teamLeader.checkNumberOfCourses(courseList); }} 测试代码: public static void main(String[] args) { Boss boss = new Boss(); TeamLeader teamLeader = new TeamLeader(); boss.commandCheckNumber(teamLeader);} 写到这里,其实功能已经都已经实现,代码看上去也没什么问题。根据迪米特原则,Boss 只想要结果,不需要跟 Course 产生直接的交流。而 TeamLeader 统计需要引用 Course 对象。Boss 和 Course 并不是朋友,从下面的类图就可以看出来: 下面来对代码进行改造: TeamLeader类: /** * @author eamon.zhang * @date 2019-09-26 上午9:17 */public class TeamLeader { public void checkNumberOfCourses() { List courseList = new ArrayList(); for (int i = 0; i < 20; i++) { courseList.add(new Course()); } System.out.println("目前已发布的课程数量是:" + courseList.size()); }} Boss 类: /** * @author eamon.zhang * @date 2019-09-26 上午9:17 */public class Boss { public void commandCheckNumber(TeamLeader teamLeader) { teamLeader.checkNumberOfCourses(); }} 再来看下面的类图,Course 和 Boss 已经没有关联了。Learn the principles of software design, must not form obsessive-compulsive disorder. When it comes to complex business scenarios, we need to improvise.
Definition of Richter scale substitution principle
The Richter substitution principle (Liskov Substitution Principle,LSP) means that if for every object o1 of type T1, there is an object of type T2 such that all program P defined by T1 does not change its behavior when all o1 objects are replaced by O2, then type T2 is a subtype of type T1.
The definition still looks rather abstract, we can re-understand that if a software entity applies a parent class, it must be applicable to its subclass, and all places that refer to the parent class must be able to transparently use the objects of its subclass. the subclass object can replace the parent object, but the program logic remains the same. Based on this understanding, let's sum up:
Extended meaning: the subclass can expand the function of the parent class, but can not change the original function of the parent class.
Subclasses can implement the abstract methods of the parent class, but cannot override the non-abstract methods of the parent class.
You can add your own unique methods to the subclass.
When the method of the subclass overloads the method of the parent class, the precondition of the method (that is, the input / input parameter of the method) is more relaxed than the input parameter of the parent method.
When the method of the subclass implements the method of the parent class (overriding / overloading or implementing the abstract method), the post-condition of the method (that is, the output / return value of the method) is stricter or equal than the parent class.
Example
When we talked about the opening and closing principle earlier, we laid a foreshadowing. We remember that when getting the discount, we rewrote the getPrice () method that overrides the parent class, adding a method to get the original price, getOriginPrice (), which obviously violates the Richter substitution principle. Let's modify the code so that we should not override the getPrice () method and add the getDiscountPrice () method:
/ * @ author eamon.zhang * @ date 2019-09-25 10:36 * / public class NovelDiscountBook extends NovelBook {public NovelDiscountBook (String name, int price, String author) {super (name, price, author);} public double getDiscountPrice () {return super.getPrice () * 0.85;}}
Using the Richter scale substitution principle has the following advantages:
The proliferation of constraint inheritance is an embodiment of the principle of opening and closing.
Strengthen the robustness of the program, at the same time, change can also achieve very good compatibility, improve the maintainability and expansibility of the program. Reduce the risks introduced when requirements change.
Now to describe a classic business scenario, explain the Richter substitution principle with the relationship between square, rectangle and quadrilateral. We all know that a square is a special rectangle, so we can create a rectangle parent class Rectangle:
/ * * @ author eamon.zhang * @ date 2019-09-26 9:59 * / public class Rectangle {private long height; private long width; public long getHeight () {return height;} public void setHeight (long height) {this.height = height;} public long getWidth () {return width;} public void setWidth (long width) {this.width = width;}}
Create a square Square class to inherit a rectangle:
/ * * @ author eamon.zhang * @ date 2019-09-26 10:01 * / public class Square extends Rectangle {private long length; public long getLength () {return length;} public void setLength (long length) {this.length = length;} @ Override public long getHeight () {return super.getHeight () } @ Override public void setHeight (long height) {super.setHeight (height);} @ Override public long getWidth () {return super.getWidth ();} @ Override public void setWidth (long width) {super.setWidth (width);}}
Create the resize () method in the test class. Based on the fact that the width of the logical rectangle should be greater than or equal to the height, we let the height increase all the time until the higher than the width becomes square:
Public static void resize (Rectangle rectangle) {while (rectangle.getWidth () > = rectangle.getHeight ()) {rectangle.setHeight (rectangle.getHeight () + 1); System.out.println ("width:" + rectangle.getWidth () + ", height:" + rectangle.getHeight ());} System.out.println ("resize method end" + "\ nwidth:" + rectangle.getWidth () + ", height:" + rectangle.getHeight ());}
Test the code:
Public static void main (String [] args) {Rectangle rectangle = new Rectangle (); rectangle.setWidth (20); rectangle.setHeight (10); resize (rectangle);}
Running result:
It is found that the height is larger than the width, which is a very normal situation in the rectangle. Now let's look at the following code, replace the rectangular Rectangle with its subclass square Square, and modify the test code:
Public static void main (String [] args) {Square square = new Square (); square.setLength (10); resize (square);}
At this time, when we run, there is a dead loop, which violates the Richter replacement principle and replaces the parent class with the subclass, and the result of the program does not meet the expectations. Therefore, there are some risks in our code design. The principle of Richter substitution exists only between parent class and subclass, and constraint inheritance is rampant. Let's create an abstract quadrilateral Quadrangle interface based on rectangle and square:
/ * * @ author eamon.zhang * @ date 2019-09-26 10:12 * / public interface Quadrangle {long getWidth (); long getHeight ();}
Modify the rectangular Rectangle class:
/ * * @ author eamon.zhang * @ date 2019-09-26 9:59 * / public class Rectangle implements Quadrangle {private long height; private long width; @ Override public long getWidth () {return width;} public long getHeight () {return height;} public void setHeight (long height) {this.height = height;} public void setWidth (long width) {this.width = width }}
Modify the square class Square class:
/ * @ author eamon.zhang * @ date 2019-09-26 10:01 * / public class Square implements Quadrangle {private long length; public long getLength () {return length;} public void setLength (long length) {this.length = length;} @ Override public long getWidth () {return length;} @ Override public long getHeight () {return length;}}
At this point, if we change the parameters of the resize () method to the quadrilateral Quadrangle class, an error will be reported inside the method.
Because the square Square no longer has setWidth () and setHeight () methods. Therefore, in order to restrict the flooding of inheritance, the method parameters of resize () can only use Rectangle rectangles. Of course, we will continue to explain it in depth in a later series of design patterns.
At this point, the study of "introduction of Dimitt's Law and Richter substitution principle in the Seven Design principles of java Design pattern" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.