This is the 15th day of my participation in Gwen Challenge
Design patterns
In the first two design patterns (1) and design Patterns (2), we have covered four principles. The next one is the Open and close principle and Demeter’s Rule.
The open closed principle
The most important and fundamental principle is open to extension, closed to modification. Through the use of interfaces and abstract classes to achieve when the program needs to be extended, can not modify the original code, to achieve a hot plug effect.
So let’s say we’re drawing a graph, and at first we’re just drawing rectangles and circles, and the code looks like this
package com.wangscaler.openclose;
/ * * *@author wangscaler
* @date2021.06.17 those * /
public class OpenClosePrinciple {
public static void main(String[] args) {
Graphic graphic = new Graphic();
graphic.drawRectangle(new Rectangle());
graphic.drawCircular(new Circular());
}
static class Graphic {
public void drawShape(Shape shape) {
if (shape.type == 1) {
drawCircular(shape);
} else if (shape.type == 2) { drawRectangle(shape); }}public void drawRectangle(Shape shape) {
System.out.println("Draw a rectangle...");
}
public void drawCircular(Shape shape) {
System.out.println("Draw a circle..."); }}static class Shape {
int type;
}
static class Circular extends Shape {
Circular() {
super.type = 1; }}static class Rectangle extends Shape {
Rectangle() {
super.type = 2; }}}Copy the code
When we add a new shape trapezoid, the code changes this way
Wrong way
package com.wangscaler.openclose;
/ * * *@author wangscaler
* @date2021.06.17 those * /
public class OpenClosePrinciple1 {
public static void main(String[] args) {
Graphic graphic = new Graphic();
graphic.drawRectangle(new Rectangle());
graphic.drawCircular(new Circular());
graphic.drawTrapezoid(new Trapezoid());
}
static class Graphic {
public void drawShape(Shape shape) {
if (shape.type == 1) {
drawCircular(shape);
} else if (shape.type == 2) {
drawRectangle(shape);
}
else if(shape.type == 3){ drawTrapezoid(shape); }}public void drawRectangle(Shape shape) {
System.out.println("Draw a rectangle...");
}
public void drawCircular(Shape shape) {
System.out.println("Draw a circle...");
}
public void drawTrapezoid(Shape shape) {
System.out.println("Draw trapezoid..."); }}static class Shape {
int type;
}
static class Circular extends Shape {
Circular() {
super.type = 1; }}static class Rectangle extends Shape {
Rectangle() {
super.type = 2; }}static class Trapezoid extends Shape {
Trapezoid() {
super.type = 3; }}}Copy the code
In this way, we can get the correct result, but there are too many code changes to achieve the hot-plug effect. We not only modified the provider’s code (adding Trapezoid), but also changed the user’s code (Graphic). We should change Shape to an abstract class. When we have a new Shape, we just need to add a new Shape class to inherit the abstract class
The right way
package com.wangscaler.openclose;
/ * * *@author wangscaler
* @date2021.06.17 those * /
public class OpenClosePrinciple2 {
public static void main(String[] args) {
Graphic graphic = new Graphic();
graphic.drawShape(new Rectangle());
graphic.drawShape(new Circular());
}
static class Graphic {
public void drawShape(Shape shape) { shape.draw(); }}static abstract class Shape {
public abstract void draw(a);
}
static class Circular extends Shape {
@Override
public void draw(a) {
System.out.println("Draw a circle..."); }}static class Rectangle extends Shape {
@Override
public void draw(a) {
System.out.println("Draw a rectangle..."); }}}Copy the code
At this point we add a new shape rectangle, just change it to
package com.wangscaler.openclose;
/ * * *@author wangscaler
* @date2021.06.17 those * /
public class OpenClosePrinciple3 {
public static void main(String[] args) {
Graphic graphic = new Graphic();
graphic.drawShape(new Rectangle());
graphic.drawShape(new Circular());
graphic.drawShape(new Trapezoid());
}
static class Graphic {
public void drawShape(Shape shape) { shape.draw(); }}static abstract class Shape {
public abstract void draw(a);
}
static class Circular extends Shape {
@Override
public void draw(a) {
System.out.println("Draw a circle..."); }}static class Rectangle extends Shape {
@Override
public void draw(a) {
System.out.println("Draw a rectangle..."); }}static class Trapezoid extends Shape {
@Override
public void draw(a) {
System.out.println("Draw trapezoid..."); }}}Copy the code
Conclusion: The open closed principle is open for extensions and closed for modifications. When we add trapezoid, we just need to add the class trapezoid to inherit the Shape abstract class and implement the methods of the abstract class. At this time, we don’t need to modify the original code, and we can achieve the result we want.
Demeter’s rule
One entity should interact with other entities as little as possible so that the functional modules of the system are relatively independent. That is, communicate only with direct friends (method parameters, member variables, method return values).
Let’s say the school principal wants to check the size of a class, so
package com.wangscaler.leastknowledgeprinciple;
import java.util.ArrayList;
import java.util.List;
/ * * *@author wangscaler
* @date2021.06.17 14:09 * /
public class LeastKnowledgePrinciple {
public static void main(String[] args) {
Principal principal = new Principal();
principal.commond(new Teacher());
}
static class Principal {
public void commond(Teacher teacher) {
List<Student> students = new ArrayList<Student>();
for (int i = 0; i < 20; i++) {
students.add(newStudent()); } teacher.count(students); }}static class Teacher {
public void count(List<Student> students) {
System.out.println("The number of students is:"+ students.size()); }}static class Student {}}Copy the code
If Student is not a direct friend of Principal, then Demeter’s rule is violated. Commond’s method does not include Student as a parameter, member variable, or method return value. So how to modify, because Student and Teacher are direct friends
package com.wangscaler.leastknowledgeprinciple;
import java.util.ArrayList;
import java.util.List;
/ * * *@author wangscaler
* @date2021.06.17 14:09 * /
public class LeastKnowledgePrinciple1 {
public static void main(String[] args) {
List<Student> students = new ArrayList<Student>();
for (int i = 0; i < 20; i++) {
students.add(new Student());
}
Principal principal = new Principal();
principal.commond(new Teacher(students));
}
static class Principal {
public void commond(Teacher teacher) { teacher.count(); }}static class Teacher {
private List<Student> students;
public Teacher(List<Student> students) {
this.students = students;
}
public void count(a) {
System.out.println("The number of students is:"+ students.size()); }}static class Student {}}Copy the code
Students become members of the teacher variable, teachers and students are direct friends, principals and teachers are direct friends.
Conclusion: As you can see from the above example, Demeter’s rule reduces coupling. Try to avoid non-direct friends (local variables) in the class.