This article was adapted from: Lebyte
This article mainly explains: 10 object-oriented design principles
For more Java related knowledge, you can follow the public account “LeByte” to send: 999
Object-oriented design principles are at the heart of OOPS programming, but most Java programmers I’ve seen are so enthusiastic about design patterns like Singletons, decorators, and observers that they don’t pay enough attention to learning object-oriented analysis and design. It’s important to learn the basics of object-oriented programming like “abstraction,” “encapsulation,” “polymorphism,” and “inheritance,” but it’s equally important to understand these design principles in order to create clean, modular designs. I often see Java programmers of all levels of experience who either don’t know the OOPS and SOLID design principles, or simply don’t know how a particular design principle benefits, or even how to use it in their coding.
The bottom line is always pursue highly cohesive, low-coupling coding or design. The Open source code for Apache and Sun is a good example of learning the Java and OOPS design principles. They show how design principles can be used in Java programming. The Java JDK uses some design principles: the factory pattern in the BorderFactory class, the singleton pattern in the Runtime class, and the decorator pattern in the java.io class. By the way, if you’re really interested in Java coding principles, read Effective Java by Joshua Bloch, who wrote Java apis. My personal favorites on object-oriented Design patterns are Kathy Sierra’s Head First Design Pattern, and others on simple object-oriented analysis and Design. These books can go a long way toward writing better code that takes advantage of various object-oriented and SOLID design patterns.
While the best way to learn design patterns (principles) is by real-world examples and understanding the inconveniences of violating them, the purpose of this article is to introduce object-oriented design principles to Java programmers who are not exposed to them or are in the learning stages. I personally feel that the OOPS and SOLID design principles need to be clearly described in an article, and I will do my best to do so, but for now be prepared to browse the following design patterns (principles) 🙂
DRY — Don’t repeat yourself
Our first object-oriented design principle is: DRY, as the name suggests, DRY(Don’t Repeat Yourself) means not writing repetitive code, but abstracting it into reusable chunks. If you have more than two identical code blocks, consider abstracting them into a separate method; Or if you use hard-coded values multiple times, set them to common constants. The advantage of this object-oriented design principle is that it is easy to maintain. It is important not to abuse this principle; repetition is not for code but for functionality. It means that if you use common code to validate the OrderID and SSN, it does not mean that they are the same or that they will remain the same from now on. By using common code to implement two different functions, or by tying the two different functions closely together; When your OrderID format changes, your SSN verification code will break. So be careful with this coupling, and don’t group together code that is similar but has nothing to do with each other.
Encapsulate frequently changed code
Encapsulate What Changes
What never changes in software is “change,” so encapsulate code that you think or suspect will be changed in the future. The advantage of this object-oriented design pattern is that it is easy to test and maintain properly encapsulated code. If you’re programming in Java, follow these guidelines: Access to variables and methods is set to be private by default, and gradually release their access, for example from “private” to “protected” or “not public.” Some design patterns in Java use encapsulation, such as the Factory design pattern, which encapsulates the code that creates objects and provides the flexibility that subsequent generation of new objects does not affect existing code.
Open/close design principles
OpenClosed Design Principle
Classes, methods/functions should be open to extension (new functionality) and closed to modification. This is another elegant SOLID design principle that prevents someone from modifying the code that passes the test. Ideally, if you add new functionality, your code should be tested, which is the goal of the on/off design principle. Incidentally, the letter “O” in SOLID refers to the on/off design principle.
Single responsibility principle
Single Responsibility Principle(SRP)
The single responsibility principle is another SOLID design principle, and the letter “S” in SOLID refers to it. According to SRP, there should be one and only one reason for a class to change, or a class should always implement a single function. If you have a class in Java that implements multiple functions, there is a coupling between those functions; If you change one of these functions, you might break the coupling, so another round of testing is needed to avoid new problems.
Dependency injection/inversion principle
Dependency Injection or Inversion principle
Don’t ask how the framework’s dependency injection will benefit you. Dependency injection is already well implemented in the Spring framework. The elegance of this design principle is: Any class injected by the DI framework is easier to test with mock objects and easier to maintain because the code that creates the objects is centralized within the framework and isolated from the client code. Dependency injection can be implemented in a variety of ways, such as using bytecode tools, some of which AOP(aspect oriented programming) frameworks such as pointcut expressions or proxies used in Spring. To learn more about this SOLID design principle, see examples from the IOC and DI design patterns. The letter “D” in SOLID refers to this design principle.
Use composition in preference to inheritance
Favor Composition over Inheritance
If possible, use composition in preference to inheritance. Some of you may argue about this, but I find composition more flexible than inheritance. Composition allows you to modify the behavior of a class at run time by setting properties, implement composition relationships between classes in the form of interfaces through the use of polymorphism, and provide flexibility for modifying composition relationships. Even Effective Java recommends using composition over inheritance.
Richter’s substitution principle
Liskov Substitution Principle LSP
According to the Richter substitution principle, where a parent class appears, it can be replaced by a subclass. For example, a method or function of a parent class should be replaced by a subclass object without any problem. LSP is closely related to the single responsibility principle and interface isolation principle. If a parent class has more functionality than its subclass, it may not support this functionality and may violate LSP design principles. In order to comply with LSP SOLID design principles, a derived class or subclass (compared to its parent class) must enhance, not decrease, its functionality. The letter “L” in SOLID indicates the LSP design principle.
Interface Isolation Principle
The interface isolation principle states that if you don’t need the functionality of an interface, don’t implement it. This mostly happens when an interface contains multiple functions and only one of them is required to implement the class. Interface design is tricky because once you publish an interface, you can’t modify it without affecting the classes that implement it. Another benefit of this design principle in Java is that an interface has a feature that requires all of the interface’s methods to be implemented before any class can use it, so using a single-purpose interface means fewer methods to be implemented.
Programming is about interfaces, not implementation objects
Programming is always about the interface, not the implementation object, which makes the structure of the code flexible and any new interface implementation object compatible with the existing code structure. So in Java, the data types of variables, method return values, and method parameters use interfaces. This is the advice of many Java programmers, as well as books such as Effective Java and Head First Design Pattern.
Acting principle
Instead of expecting a single class to do everything, delegate some functionality to proxy classes as appropriate. Examples of the proxy principle are the Equals () and hashCode() methods in Java. To compare the contents of two objects, we let the classes used for the comparison do the comparison themselves rather than their callers. The advantage of this design principle is that there is no duplication of coding and it is easy to modify the behavior of classes.
conclusion
All of the above object-oriented design principles can help you write flexible, elegant code: code structures with high cohesion and low coupling. The theory is only the first step, but it is more important to acquire the ability to see when to use these design principles. To find out if we violated any design principles and affected the flexibility of the code, but nothing in the world is perfect, and we can’t always solve problems using design patterns and design principles, which are mostly used in large enterprise projects with long maintenance cycles
Thank you for your recognition and support, xiaobian will continue to forward “LeByte” quality articles