Moment For Technology

Seven principles of design patterns

Posted on Aug. 5, 2023, 9:09 a.m. by Hayley Price
Category: The back-end Tag: The back-end

- Single responsibility principle

For classes, that is, a class should be responsible for only one responsibility. For example, class A is responsible for two different responsibilities: Responsibility 1, responsibility 2. When the requirements of responsibility 1 change and A changes, it may cause the execution error of responsibility 2, so the granularity of class A needs to be decomposed into A1 and A2

public class SingleResponsibility1 { public static void main(String[] args) { // TODO Auto-generated method stub Vehicle  vehicle = new Vehicle(); (" motorcycle "); Vehicle. The run (" car "); Vehicle. The run (" aircraft "); }} // Vehicle class // mode 1 // 1. In mode 1's run method, the single responsibility principle is violated // 2. The solution is very simple, depending on the operation method of the vehicle, Class Vehicle {public void run(String Vehicle) {system.out.println (Vehicle + "....") ); }}Copy the code
package com.atguigu.principle.singleresponsibility; public class SingleResponsibility2 { public static void main(String[] args) { // TODO Auto-generated method stub RoadVehicle roadVehicle = new RoadVehicle(); (" motorcycle "); RoadVehicle. Run (" car "); AirVehicle airVehicle = new AirVehicle(); AirVehicle. Run (" aircraft "); }} // Analysis of Option 2 //1. Adherence to the principle of single responsibility //2. But this is a big change, which is to decompose the class and modify the client //3. Modify the Vehicle class directly, Class RoadVehicle {public void run(String vehicle) {system.out.println (vehicle + "RoadVehicle "); }} Class AirVehicle {public void run(String vehicle) {system.out.println (vehicle + "skyrun "); }} Class vehicle {public void run(String vehicle) {system.out.println (vehicle + "water "); }}Copy the code
package com.atguigu.principle.singleresponsibility; public class SingleResponsibility3 { public static void main(String[] args) { // TODO Auto-generated method stub Vehicle2 vehicle2 = new Vehicle2(); Vehicle2. Run (" car "); Vehicle2. RunWater (" ship "); Vehicle2. RunAir (" aircraft "); }} //1. This method does not make a big change to the original class, just add method //2. While the single responsibility principle is not observed at the class level, at the method level, Class Vehicle2 {public void run(String vehicle) {// Handle system.out.println (vehicle + "run on the road...." ); } public void runAir(String vehicle) {system.out.println (vehicle + "....") ); } public void runWater(String vehicle) {system.out.println (vehicle + "....") ); } // Method 2. //.. / /.. / /... }Copy the code

- Interface isolation rules

A client should not rely on interfaces it does not need, that is, the dependency of one class on another should be based on the smallest interface

- Dependence inversion principle

  1. A high-level module should not depend on a low-level module; both should depend on its abstraction
  2. Abstractions should not depend on details, details should depend on abstractions
  3. The central idea of dependency inversion is interface oriented programming
  4. The dependency inversion principle is based on the design idea that abstract things are more stable than details. An architecture based on abstraction is much more stable than one based on detail. In Java, abstraction refers to an interface or abstract class, and details are concrete implementation classes
  5. The purpose of using interfaces or abstract classes is to create specifications that do not involve any concrete operations, leaving the task of presenting the details to their implementation classes
Public class DependecyInversion {public static void main(String[] args) {Person = new Person(); person.receive(new Email()); person.receive(new WeiXin()); Interface IReceiver {public String getInfo(); } class Email implements IReceiver {public String getInfo() {return "Email: hello,world"; } // implements IReceiver {public String getInfo() {return "implements: hello,ok"; Public void receive(IReceiver receiver) {public void receive(IReceiver receiver) { System.out.println(receiver.getInfo()); }}Copy the code

Rely on the notes and details of the inversion principle

  1. Low-level modules should have abstract classes or interfaces, or both, for better program stability.
  2. Variables are declared as abstract classes or interfaces as possible, so that there is a buffer layer between our variable references and the actual object, which facilitates program expansion and optimization
  3. Inheritance follows the Richter substitution principle

- Richter's substitution principle

  1. The Liskov Substitution Principle was coined in 1988 by a lady named Lee at MIT.
  2. If for every object o1 of type T1 there is an object O2 of type T2, such that the behavior of all programs P defined by T1 does not change when all objects o1 are substituted for O2, then type T2 is a subtype of type T1. In other words, all references to a base class must be able to transparently use objects from its subclasses.
  3. When using inheritance, follow the Richter's substitution principle and try not to override methods of the parent class in subclasses
  4. Richter's substitution principle tells us that inheritance actually makes two classes more coupled, and can be solved by aggregation, composition, and dependency, where appropriate
public class Liskov { public static void main(String[] args) { // TODO Auto-generated method stub A a = new A(); System.out.println("11-3=" + a.func1(11, 3)); System.out.println("1-8=" + a.func1(1, 8)); System.out.println("-----------------------"); B b = new B(); Println ("11+3=" + b.unc1 (11, 3)); // Func1 is not A subtraction function. Println ("1+8=" + b.fus1 (1, 8)); // 1+8 System.out.println("11+3+9=" + b.func2(11, 3)); System.out.println("11-3=" + b.unc3 (11, 3)); system.out. println("11-3=" + b.unc3 (11, 3)); Class A extends Base {// Returns the difference between two numbers public int func1(int num1, int num2) { return num1 - num2; Class B extends Base {private A A = new A(); private A A = new A(); Public int func1(int A, int b) {return A + b; } public int func2(int a, int b) { return func1(a, b) + 9; } public int func3(int A, int b) {return this.a.func1(A, b); }}Copy the code

- Open and close principle

  1. The Open Closed Principle is the most fundamental and important design Principle in programming
  2. A software entity such as classes, modules, and functions should be open to extension (providers) and closed to modification (users). Build the framework with abstractions and extend the details with implementations.
  3. When software needs to change, try to do so by extending the behavior of software entities rather than by modifying existing code.
  4. The purpose of following other principles in programming and using design patterns is to follow the open closed principle.
package com.atguigu.principle.ocp.improve; Public class Ocp {public static void main(String[] args) {public class Ocp {public static void main(String[] args) GraphicEditor(); graphicEditor.drawShape(new Rectangle()); graphicEditor.drawShape(new Circle()); graphicEditor.drawShape(new Triangle()); graphicEditor.drawShape(new OtherGraphic()); Public void drawShape(Shape s) {s.draw();}} public void drawShape(Shape s) {s.draw(); }} //Shape class, base class Shape {int m_type; public abstract void draw(); Rectangle extends Shape {Rectangle() {super.m_type = 1; } @override public void draw() {// TODO auto-generated method stub system.out.println (" draw rectangle "); } } class Circle extends Shape { Circle() { super.m_type = 2; } @override public void draw() {// TODO auto-generated method stub system.out.println (" draw circle "); }} class Triangle extends Shape {Triangle() {super.m_type = 3; } @override public void draw() {// TODO auto-generated method stub system.out.println (" draw triangle "); // TODO auto-generated method stub system.out.println (" draw triangle "); }} class OtherGraphic extends Shape {OtherGraphic() {super.m_type = 4; } @override public void draw() {// TODO auto-generated method stub system.out.println (" draw other graphs "); }}Copy the code

- Demeter's rule

  1. One object should have minimal knowledge of other objects
  2. The closer the relationship between classes is, the greater the coupling degree is
  3. The Demeter Principle, also known as the least known Principle, states that a class knows as little as possible about the classes it depends on. That is, for dependent classes, no matter how complex, try to encapsulate the logic inside the class. Do not disclose any information except for the provided public method
  4. There's a simpler definition of Demeter's rule: Only communicate with direct friends
  5. Direct friends: Every object is coupled to other objects, and as long as there is a coupling between two objects,

Let's say the two objects are friends. There are many ways of coupling: dependency, association, composition, aggregation, etc. Where, we call the classes that appear in member variables, method parameters, and method return values as direct friends, while the classes that appear in local variables are not direct friends. That is, unfamiliar classes are best kept from appearing inside the class as local variables.

// client public class Demeter1 {public static void main(String[] args) {system.out.println ("~~~ ~ using Demeter1 "); // create a SchoolManager object SchoolManager = new SchoolManager(); / / output college staff headquarters staff id and school information schoolManager. PrintAllEmployee (new CollegeManager ()); } // Class Employee {private String id; public void setId(String id) { = id; } public String getId() { return id; Class CollegeEmployee {private String id; public void setId(String id) { = id; } public String getId() { return id; Class CollegeManager {public ListCollegeEmployee getAllEmployee() { ListCollegeEmployee list = new ArrayListCollegeEmployee(); for (int i = 0; i  10; List CollegeEmployee emp = new CollegeEmployee(); Emp. setId(" id= "+ I); list.add(emp); } return list; } public void printEmployee() {ListCollegeEmployee list1 = getAllEmployee(); System. The out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- college staff -- -- -- -- -- -- -- -- -- -- -- -- "); for (CollegeEmployee e : list1) { System.out.println(e.getId()); CollegeManager CollegeEmployee = CollegeManager CollegeEmployee = collegManager CollegeEmployee = collegManager CollegeEmployee Public ListEmployee getAllEmployee() {ListEmployee List = new ArrayListEmployee(); for (int i = 0; i  5; Emp = new Employee(); emp = new Employee(); Emp. setId(" id= "+ I); list.add(emp); } return list; } void printAllEmployee(CollegeManager Sub) {// Check the problem //1. Package the CollegeManager sub.printemployee () to export the college staff method. ListEmployee list2 = this.getallemployee (); System. The out. Println (" -- -- -- -- -- -- -- -- -- -- -- -- the school headquarters staff -- -- -- -- -- -- -- -- -- -- -- -- "); for (Employee e : list2) { System.out.println(e.getId()); }}}Copy the code

Demeter's Rule notes and details

  1. The core of Demeter's law is to reduce coupling between classes
  2. Note, however, that because each class reduces unnecessary dependencies, Demeter's rule requires only a reduction in coupling between classes (objects), not a complete absence of dependencies

- Synthetic reuse principle

The rule is to use composition/aggregation rather than inheritance whenever possible

About (Moment For Technology) is a global community with thousands techies from across the global hang out!Passionate technologists, be it gadget freaks, tech enthusiasts, coders, technopreneurs, or CIOs, you would find them all here.