7 major design principles of software (with case code)

Table of contents

1. The principle of opening and closing

2. Single Responsibility Principle

3. Liskov substitution principle

3.1 Before use

3.1. After use

4. Dependency Inversion Principle

4.1. Before use

4.2 After use

5. Interface isolation principle

5.1. Before use

5.2. After use

6. Law of Demeter

7. Principles of synthesis and reuse

8. Code written in this blog

In software development, in order to improve the maintainability and reusability of the software system and increase the scalability and flexibility of the software, programmers should try their best to develop programs according to software design principles, thereby improving software development efficiency and saving software development. costs and maintenance costs.

1. The principle of opening and closing

concept: The Open Closed Principle is the most basic and important design principle in programming; Open for extension, closed for modification. When the program needs to be expanded, the original code cannot be modified to achieve a hot-plug effect. In short, it is to make the program expandable, easy to maintain and upgrade. To achieve this effect, we need to use interfaces and abstract classes. Because the abstraction is flexible and adaptable, as long as the abstraction is reasonable, the stability of the software architecture can be basically maintained. The volatile details in the software can be extended from the implementation class derived from abstraction. When the software needs to change, it is only necessary to re-derive an implementation class to extend according to the requirements.

Case: Requirement: Switch skins for hero Garen

Code:

package com.jie.principles.lockage;
/**
 * @description:abstract skin class
 * @author: jie 
 * @time: 2022/1/28 11:00
 */
public abstract class Skin {

    /**
     * @description:show skin
     * @author: jie
     * @time: 2022/1/28 12:18
     */
    public abstract void display();

}
copy
package com.jie.principles.lockage;
/**
 * @description:Default skin Might of Demacia
 * @author: jie
 * @time: 2022/1/28 12:02
 */
public class DefaultSkin extends Skin{

    @Override
    public void display() {
        System.out.println("Might of Demacia: Garen");
    }
}
copy
package com.jie.principles.lockage;
/**
 * @description:battle academy
 * @author: jie
 * @time: 2022/1/28 12:05
 */
public class BattleAcademy extends Skin{
    @Override
    public void display() {
        System.out.println("Battle Academy: Galen");
    }
}
copy
package com.jie.principles.lockage;
/**
 * @description:Galen
 * @author: jie 
 * @time: 2022/1/28 12:07
 */
public class Garen {

    /**
     * @description:skin
     * @author: jie
     * @time: 2022/1/28 12:11
     */
    private Skin skin;

    public Skin getSkin() {
        return skin;
    }

    public void setSkin(Skin skin) {
        this.skin = skin;
    }

    
    public void display(){
        skin.display();
    }
}
copy
package com.jie.principles.lockage;

/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 12:12
 */
public class Test {

    public static void main(String[] args) {
        //default skin
        defaultSkin();
        //battle academy skins
        battleAcademy();

    }

    /**
     * @description:default skin
     * @author: jie
     * @time: 2022/1/28 12:27
     */
    public static void defaultSkin() {
        //1. Create a Galen object
        Garen garen = new Garen();
        //2. Create a default skin object
        DefaultSkin defaultSkin = new DefaultSkin();
        //3. Set the skin to Galen
        garen.setSkin(defaultSkin);
        //4. Display the skin
        garen.display();
    }

    /**
     * @description:battle academy
     * @author: jie
     * @time: 2022/1/28 12:31
     */
    public static void battleAcademy() {
        //1. Create a Galen object
        Garen garen = new Garen();
        //2. Create a battle skin object
        BattleAcademy battleAcademy = new BattleAcademy();
        //3. Set the skin to Galen
        garen.setSkin(battleAcademy);
        //4. Display the skin
        garen.display();
    }

}
copy

Test Results

Changes in requirements: At this time, it is necessary to add Garen's new skin God King

package com.jie.principles.lockage;
/**
 * @description:god king
 * @author: jie
 * @time: 2022/1/28 12:47
 */
public class Gods extends Skin{

    @Override
    public void display() {
        System.out.println("God King: Galen");
    }
}
copy
package com.jie.principles.lockage;

/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 12:12
 */
public class Test {

    public static void main(String[] args) {
        //god king
        gods();
    }
    
    /**
     * @description:god king
     * @author: jie
     * @time: 2022/1/28 12:49
     */
    public static void gods() {
        //1. Create a Galen object
        Garen garen = new Garen();
        //2. Create the God King skin object
        Gods gods = new Gods();
        //3. Set the skin to Galen
        garen.setSkin(gods);
        //4. Display the skin
        garen.display();
    }
}
copy

Test Results:

summary: Following the open-closed principle, the class with Skin as the main body does not need to be modified; it only needs to extend its subclasses; This is what "open for extension, closed for modification" means;

2. Single Responsibility Principle

concept Reduce the complexity of the class, a class is only responsible for one responsibility Improve the readability and maintainability of the class Reduce the risk caused by changes, and try to only add new and do not modify the code on the server side

The above skin case also reflects the single responsibility principle:

After using a single responsibility: the skin is handed over to each subclass to implement, and one class is responsible for one skin;

3. Liskov substitution principle

concept: The Liskov Substitution Principle is one of the basic principles of object-oriented design. Liskov Substitution Principle: Wherever a base class can appear, a subclass must appear. Popular understanding: subclasses can extend the functions of the parent class, but cannot change the original functions of the parent class. In other words, when a subclass inherits the parent class, try not to override the parent class's methods except adding new methods to complete the new functions. If the new function is completed by overriding the method of the parent class, although it is simple to write, the reusability of the entire inheritance system will be relatively poor, especially when polymorphism is used frequently, the probability of program running error will be very large. . Problems can be solved by aggregation, composition, dependency where appropriate

Case: Requirements: Complete the subtraction of two numbers and encapsulate it into a calculator; there are many types of calculators (arithmetic calculators, scientific calculators, program calculators....)

3.1 Before use

First, simply implement the subtraction function of the arithmetic calculator;

package com.jie.principles.Richter;
/**
 * @description:parent class of all computers
 * @author: jie
 * @time: 2022/1/28 13:49
 */
public abstract class Cal {
    protected abstract double minus(double x, double y);
}
copy
package com.jie.principles.Richter;
/**
 * @description:The most basic arithmetic calculator
 * @author: jie
 * @time: 2022/1/28 13:53
 */
class BaseCountCal extends Cal {

    @Override
    protected double minus(double x, double y) {
        return x - y;
    }
}
copy
package com.jie.principles.Richter;
/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 13:55
 */
public class Test {
    public static void main(String[] args) {
        Cal cal = new BaseCountCal();
        //Subtraction of 6 and 3
        System.out.println(cal.minus(6, 3));
    }
}
copy

Test Results:

Requirements change, need to make a program calculator to complete the subtraction of two numbers

/**
 * @description:Complete the subtraction of the program calculator
 * @author: jie
 * @time: 2022/1/28 14:05
 */
class ProcessCal extends Cal{

    @Override
    protected double minus(double x, double y) {
        return x+y;
    }
}
copy
package com.jie.principles.Richter;

/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 13:55
 */
public class Test {
    public static void main(String[] args) {
        Cal cal = new BaseCountCal();
        //Complete the subtraction of 6 and 3 (Basic Arithmetic Calculator)
        System.out.println(cal.minus(6, 3));
        //Complete the Subtraction of 6 and 3 (Program Calculator)
        cal = new ProcessCal();
        System.out.println(cal.minus(6, 3));
    }
}
copy

As can be seen from the above Does not follow the Liskov substitution principle: the subtraction of two numbers defined by Cal is directly overwritten by the subclass ProcessCal, and the result of the overwrite causes the caller Test to fail to get the desired result when using it; the reason is that the program class and the High coupling between classes (inheritance relationship)

3.1. After use

package com.jie.principles.Richter;
/**
 * @description:Complete the subtraction of the program calculator
 * @author: jie
 * @time: 2022/1/28 14:05
 */
class ProcessCal extends Cal{

    /**
     * @description:Aggregate the Cal abstract class, refer to it unchanged, and do not refer to changes
     * @author: jie
     * @time: 2022/1/28 14:33
     */
    private Cal cal;

    public ProcessCal(Cal cal) {
        this.cal = cal;
    }

    @Override
    protected double minus(double x, double y) {
        return cal.minus(x, y) ;
    }
}
copy
package com.jie.principles.Richter;

/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 13:55
 */
public class Test {
    public static void main(String[] args) {
        Cal cal = new BaseCountCal();
        //Complete the subtraction of 6 and 3 (Basic Arithmetic Calculator)
        System.out.println(cal.minus(6, 3));

        //Complete the Subtraction of 6 and 3 (Program Calculator)
        ProcessCal processCal = new ProcessCal(cal);
        System.out.println(processCal.minus(6, 3));
    }
}
copy

Test Results:

Follow the Liskov substitution principle: the subtraction of two numbers defined by Cal, the majority behavior (addition, multiplication and division) of the ProcessCal class is consistent with the Cal class. At this time, the aggregation/combination method should be used, which decouples the process between ProcessCal and Cal. relationship, when the caller Test uses the subtraction operation, it will pay more attention to the implementation process of ProcessCal subtraction; This is what Liskov replacement said. It is recommended to use aggregation/combination to solve dependencies, and subclasses try not to override the methods of parent classes;

4. Dependency Inversion Principle

High-level modules should not depend on low-level modules, both should depend on their abstractions. Abstractions should not depend on details, and details should depend on abstractions. The central idea of ​​dependency inversion (inversion) is interface-oriented programming. Low-level modules should have abstract classes or interfaces as much as possible, or both, for better program stability. The declared type of the variable should be an abstract class or interface as much as possible, so that there is a buffer layer between our variable reference and the actual object, which is conducive to program expansion and optimization.

Case:

Requirement: Teachers chat with students through different APP s

Realize the teacher's interaction needs with students through WeChat and Button;

4.1. Before use

package com.jie.principles.relyonreverse;
/**
 * @description:WeChat
 * @author: jie
 * @time: 2022/1/28 15:31
 */
class WeiXin{
    public String info;

    public String getInfo() {
        return info;
    }

    public WeiXin(String info) {
        this.info = info;
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:QQ
 * @author: jie
 * @time: 2022/1/28 15:31
 */
class QQ{
    public String info;

    public String getInfo() {
        return info;
    }

    public QQ(String info) {
        this.info = info;
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:teacher
 * @author: jie
 * @time: 2022/1/28 15:30
 */
public class Teacher {
    public void receiveWeiXin(WeiXin weiXin){
        System.out.println(weiXin.getInfo());
    }

    public void receiveQQ(QQ qq){
        System.out.println(qq.getInfo());
    }
}
copy

Changes in demand: The teacher has added a channel "Dingding" to obtain student information

package com.jie.principles.relyonreverse;
/**
 * @description:Dingding
 * @author: jie
 * @time: 2022/1/28 15:36
 */
class DingDing{
    private String info;

    public String getInfo() {
        return info;
    }

    public DingDing(String info) {
        this.info = info;
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:teacher
 * @author: jie
 * @time: 2022/1/28 15:30
 */
public class Teacher {
    public void receiveWeiXin(WeiXin weiXin){
        System.out.println(weiXin.getInfo());
    }

    public void receiveQQ(QQ qq){
        System.out.println(qq.getInfo());
    }

    public void receiveDing(DingDing dingDing){
        System.out.println(dingDing.getInfo());
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:teacher
 * @author: jie
 * @time: 2022/1/28 15:30
 */
public class Teacher {
    public void receiveWeiXin(WeiXin weiXin){
        System.out.println(weiXin.getInfo());
    }

    public void receiveQQ(QQ qq){
        System.out.println(qq.getInfo());
    }

    public void receiveDing(DingDing dingDing){
        System.out.println(dingDing.getInfo());
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 15:31
 */
public class Test {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.receiveQQ(new QQ("qq message sent"));
        teacher.receiveWeiXin(new WeiXin("Message sent by WeChat"));
        teacher.receiveDing(new DingDing("message sent by DingTalk"));
    }
}
copy

As can be seen from the above The caller-high-level module (Teacher class) depends on the low-level module (WinXin class, QQ class), the consequence of this is that when the low-level module expands, the high-level module needs to make certain adjustments; this violates the open-closed principle;

4.2 After use

package com.jie.principles.relyonreverse;
/**
 * @description:Interface App
 * @author: jie 
 * @time: 2022/1/28 15:47
 */
interface App{
    String getInfo();
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:teacher
 * @author: jie
 * @time: 2022/1/28 15:30
 */
public class Teacher {
    public void receive(App app){
        System.out.println(app.getInfo());
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:WeChat
 * @author: jie
 * @time: 2022/1/28 15:31
 */
class WinXin implements App{
    private String info;

    public WinXin(String info) {
        this.info = info;
    }

    @Override
    public String getInfo() {
        return info;
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:QQ
 * @author: jie
 * @time: 2022/1/28 15:31
 */
class QQ implements App{
    private String info;

    public QQ(String info) {
        this.info = info;
    }

    @Override
    public String getInfo() {
        return info;
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 15:31
 */
public class Test {
    public static void main(String[] args) {
        Teacher teacher =new Teacher();
        teacher.receive(new WinXin("Message from WeChat"));
        teacher.receive(new QQ("qq message from"));
    }
}
copy

Changes in demand: The teacher has added a channel "Dingding" to obtain student information

package com.jie.principles.relyonreverse;
/**
 * @description:Dingding
 * @author: jie
 * @time: 2022/1/28 15:36
 */
class DingDing implements App {
    private String info;

    public DingDing(String info) {
        this.info = info;
    }

    @Override
    public String getInfo() {
        return info;
    }
}
copy
package com.jie.principles.relyonreverse;
/**
 * @description:test class
 * @author: jie
 * @time: 2022/1/28 15:31
 */
public class Test {
    public static void main(String[] args) {
        Teacher teacher =new Teacher();
        teacher.receive(new WinXin("Message from WeChat"));
        teacher.receive(new QQ("qq message from"));
        teacher.receive(new DingDing("Message from DingTalk"));
    }
}
copy

As can be seen from the above The caller-high-level module (Teacher class) depends on the abstraction (App interface) corresponding to the low-level module. At this time, the low-level module expands, and the high-level module is not affected, which conforms to the open-closed principle;

5. Interface isolation principle

concept: A client shouldn't be forced to depend on methods it doesn't use; dependencies of one class on another should be built on a minimal interface.

Case:

Requirements: The safety door has the functions of fire prevention, waterproof and anti-theft.

5.1. Before use

package com.jie.principles.quarantine;
/**
 * @description:Safety door function interface
 * @author: jie
 * @time: 2022/1/28 16:23
 */
public interface SafetyDoor {
    /**
     * @description:fireproof
     * @author: jie
     * @time: 2022/1/28 16:27
     */
    void fireproofing();
    /**
     * @description:water proof
     * @author: jie
     * @time: 2022/1/28 16:29
     */
    void waterproof();
    /**
     * @description:anti-theft
     * @author: jie
     * @time: 2022/1/28 16:30
     */
    void antiTheft();
}
copy
package com.jie.principles.quarantine;
/**
 * @description:A Brand Safety Door
 * @author: jie
 * @time: 2022/1/28 16:32
 */
public class ASafetyGate implements SafetyDoor{
    @Override
    public void fireproofing() {
        System.out.println("fireproof");
    }

    @Override
    public void waterproof() {
        System.out.println("water proof");
    }

    @Override
    public void antiTheft() {
        System.out.println("anti-theft");
    }
}
copy
package com.jie.principles.quarantine;
/**
 * @description:client
 * @author: jie
 * @time: 2022/1/28 16:41
 */
public class Client {
    public static void main(String[] args) {
        //A brand security door
        ASafetyGate aSafetyGate = new ASafetyGate();
        aSafetyGate.antiTheft();
        aSafetyGate.fireproofing();
        aSafetyGate.waterproof();
    }
}
copy

Changes in demand: Need to increase the security door of brand B, and only need the function of anti-theft.

package com.jie.principles.quarantine;
/**
 * @description:B Brand Safety Door
 * @author: jie
 * @time: 2022/1/28 16:32
 */
public class BSafetyGate implements SafetyDoor{
    @Override
    public void fireproofing() {
        System.out.println("fireproof");
    }

    @Override
    public void waterproof() {
        System.out.println("water proof");
    }

    @Override
    public void antiTheft() {
        System.out.println("anti-theft");
    }
}
copy
package com.jie.principles.quarantine;

import com.jie.principles.lockage.BattleAcademy;

/**
 * @description:client
 * @author: jie
 * @time: 2022/1/28 16:41
 */
public class Client {
    public static void main(String[] args) {
        //A brand security door
        ASafetyGate aSafetyGate = new ASafetyGate();
        aSafetyGate.antiTheft();
        aSafetyGate.fireproofing();
        aSafetyGate.waterproof();
        System.out.println("_____________________________________________________");
        //B brand security door
        BSafetyGate bSafetyGate = new BSafetyGate();
        bSafetyGate.antiTheft();
        bSafetyGate.fireproofing();
        bSafetyGate.waterproof();
    }
}
copy

As can be seen from the above BSafetyGate implements SafetyDoor, but BSafetyGate only needs the function of anti-theft. Obviously violates the principle of interface isolation.

5.2. After use

package com.jie.principles.quarantine;
/**
 * @description:Fire interface
 * @author: jie
 * @time: 2022/1/28 17:57
 */
public interface Fireproof {
    void fireproof();
}
copy
package com.jie.principles.quarantine;
/**
 * @description:Waterproof interface
 * @author: jie
 * @time: 2022/1/28 17:56
 */
public interface Waterproof {
    void waterproof();
}
copy
package com.jie.principles.quarantine;
/**
 * @description:Anti-theft interface
 * @author: jie
 * @time: 2022/1/28 17:57
 */
public interface AntiTheft {
    void antiTheft();
}
copy
package com.jie.principles.quarantine;
/**
 * @description:A Brand Safety Door
 * @author: jie
 * @time: 2022/1/28 16:32
 */
public class ASafetyGate implements AntiTheft,Fireproof,Waterproof{
    @Override
    public void antiTheft() {
        System.out.println("anti-theft");
    }

    @Override
    public void fireproof() {
        System.out.println("fireproof");
    }


    @Override
    public void waterproof() {
        System.out.println("water proof");
    }
}
copy
package com.jie.principles.quarantine;
/**
 * @description:B Brand Safety Door
 * @author: jie
 * @time: 2022/1/28 16:32
 */
public class BSafetyGate implements AntiTheft{
    @Override
    public void antiTheft() {
        System.out.println("anti-theft");
    }
}
copy
package com.jie.principles.quarantine;

import com.jie.principles.lockage.BattleAcademy;

/**
 * @description:client
 * @author: jie
 * @time: 2022/1/28 16:41
 */
public class Client {
    public static void main(String[] args) {
        //A brand security door
        ASafetyGate aSafetyGate = new ASafetyGate();
        aSafetyGate.antiTheft();
        aSafetyGate.fireproof();
        aSafetyGate.waterproof();
        System.out.println("_____________________________________________________");
        //B brand security door
        BSafetyGate bSafetyGate = new BSafetyGate();
        bSafetyGate.antiTheft();
    }
}
copy

6. Law of Demeter

The Law of Demeter is also known as the principle of least knowledge. Talk only to your immediate friends and not to strangers. The implication is that if two software entities do not need to communicate directly, then there should be no direct mutual call, and the call can be forwarded by a third party. Its purpose is to reduce the coupling between classes and improve the relative independence of modules. The "friend" in the Law of Demeter refers to: the current object itself, the member objects of the current object, the objects created by the current object, the method parameters of the current object, etc. These objects are associated, aggregated or combined with the current object, and can be methods to directly access these objects. In fact, it is another embodiment of the single responsibility principle, encapsulate and re-encapsulate functions, and do not redundantly combine all functions;

Case:

Demand: Because celebrities are fully devoted to their work, many daily affairs are handled by agents, such as meeting with fans and negotiating business with media companies. Agents here are friends of stars, while fans and media companies are strangers.

package com.jie.principles.Dimit;
/**
 * @description:star
 * @author: jie
 * @time: 2022/1/28 18:35
 */
public class Star {
    private String name;

    public Star(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}
copy
package com.jie.principles.Dimit;
/**
 * @description:fan
 * @author: jie
 * @time: 2022/1/28 18:35
 */
public class Fans {
    private String name;

    public Fans(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}
copy
package com.jie.principles.Dimit;
/**
 * @description:media company
 * @author: jie
 * @time: 2022/1/28 18:36
 */
public class Company {
    private String name;

    public Company(String name) {
        this.name=name;
    }

    public String getName() {
        return name;
    }
}
copy
package com.jie.principles.Dimit;

/**
 * @description:Interface with media companies
 * @author: jie
 * @time: 2022/1/28 18:42
 */
public interface Business {
   /**
     * @description:How to negotiate with media companies
     * @author: jie
     * @time: 2022/1/28 18:38
     */
    void business();

}
copy
package com.jie.principles.Dimit;
/**
 * @description:interface with fans
 * @author: jie
 * @time: 2022/1/28 18:39
 */
public interface Meeting {
   /**
     * @description:How to meet fans
     * @author: jie
     * @time: 2022/1/28 18:38
     */
    void meeting();
}
copy
package com.jie.principles.Dimit;
/**
 * @description:broker
 * @author: jie
 * @time: 2022/1/28 18:36
 */
public class Agent implements Meeting,Business{
    /**
     * @description:star
     * @author: jie
     * @time: 2022/1/28 18:37
     */
    private Star star;
    /**
     * @description:fan
     * @author: jie
     * @time: 2022/1/28 18:37
     */
    private Fans fans;
    /**
     * @description:media company
     * @author: jie
     * @time: 2022/1/28 18:37
     */
    private Company company;

    public void setStar(Star star) {
        this.star = star;
    }

    public void setFans(Fans fans) {
        this.fans = fans;
    }

    public void setCompany(Company company) {
        this.company = company;
    }
  
    @Override
    public void meeting() {
        System.out.println(fans.getName() + "with stars" + star.getName() + "met.");
    }
   
    @Override
    public void business() {
        System.out.println(company.getName() + "with stars" + star.getName() + "Negotiating business.");
    }
}
copy
package com.jie.principles.Dimit;

/**
 * @description:client
 * @author: jie
 * @time: 2022/1/28 18:47
 */
public class Client {

    public static void main(String[] args) {
        //1. Create a broker class
        Agent agent = new Agent();
        //2. Create a star object
        Star star = new Star("Zhang San");
        agent.setStar(star);
        //Create a fan object
        Fans fans = new Fans("Li Si");
        agent.setFans(fans);
        //Create a media company object
        Company company = new Company("Invitrogen Media");
        agent.setCompany(company);

        //and fans
        agent.meeting();
        //and media companies
        agent.business();
    }

}
copy

7. Principles of synthesis and reuse

The principle of composition and reuse means: try to use the association relationship such as composition or aggregation to realize it first, and then consider using the inheritance relationship to realize it. Generally, there are two types of class reuse: inheritance reuse and composition reuse. Although inheritance and reuse has the advantages of simplicity and ease of implementation, it also has the following disadvantages:

  1. Inheritance reuse destroys class encapsulation. Because inheritance exposes the implementation details of the parent class to the child class, the parent class is transparent to the child class, so this reuse is also called "white box" reuse.
  2. The coupling between the subclass and the superclass is high. Any change in the implementation of the parent class will lead to changes in the implementation of the subclass, which is not conducive to the extension and maintenance of the class.
  3. It limits the flexibility of reuse. The implementation inherited from the parent class is static, defined at compile time, so it cannot change at runtime.

When using combination or aggregation reuse, existing objects can be incorporated into new objects to make them part of the new object, and the new object can call the functions of the existing object, which has the following advantages:

  1. It maintains class encapsulation. Because the internal details of the component objects are invisible to the new objects, this reuse is also known as "black box" reuse.
  2. The coupling between objects is low. An abstraction can be declared at the member position of a class.
  3. High flexibility of reuse. This reuse can be done dynamically at runtime, and new objects can dynamically reference objects of the same type as the constituent objects.

8. Code written in this blog

Software Design Principles: Code Typed by Cases of Software Design Principles

Tags: OOP

Posted by $username on Mon, 07 Nov 2022 08:47:07 +0300