This is the 16th day of my participation in Gwen Challenge

Design patterns

We have covered six design principles: the single responsibility principle, interface isolation principle, dependency reversal principle, Richter’s substitution principle, Open and close principle, and Demeter’s Rule. This article will introduce the last synthetic reuse principle and three ways of passing dependencies.

Principle of composite reuse

Try to use composition/aggregation rather than inheritance.

At the beginning, A has two methods, and B needs those two methods, so the most straightforward thing to do is to inherit.

package com.wangscaler.compositereuseprinciple;

/ * * *@author wangscaler
 * @date 2021.06.17 14:50
 */
public class CompositeReusePrinciple {
    public static void main(String[] args) {
        B b = new B();
        b.test();
    }

    static class A {
        void test(a) {
            System.out.println("test");
        }

        void test1(a) {
            System.out.println("test1"); }}static class B extends A {}}Copy the code

In this way, WE simply let B have the functions of test and test1. However, with the development of business, A added test2 and test3 methods, which were unnecessary to B, which greatly increased the coupling. So there are three ways to modify code according to the principle of composite reuse.

Method 1: synthesis

package com.wangscaler.compositereuseprinciple;

/ * * *@author wangscaler
 * @date 2021.06.17 14:50
 */
public class CompositeReusePrinciple1 {
    public static void main(String[] args) {
        B b = new B();
        b.test();
    }

    static class A {
        void test(a) {
            System.out.println("test");
        }

        void test1(a) {
            System.out.println("test1"); }}static class B {
        A a = new A();

        void test(a) { a.test(); }}}Copy the code

Mode 2: dependence

package com.wangscaler.compositereuseprinciple;

/ * * *@author wangscaler
 * @date 2021.06.17 14:50
 */
public class CompositeReusePrinciple2 {
    public static void main(String[] args) {
        B b = new B();
        b.test(new A());
    }

    static class A {
        void test(a) {
            System.out.println("test");
        }

        void test1(a) {
            System.out.println("test1"); }}static class B {
        void test(A a) {
            a.test();
        }

        void test1(A a) { a.test1(); }}}Copy the code

Method 3: Aggregation

package com.wangscaler.compositereuseprinciple;

/ * * *@author wangscaler
 * @date 2021.06.17 14:50
 */
public class CompositeReusePrinciple3 {
    public static void main(String[] args) {
        B b = new B();
        b.setA(new A());
        b.test();
    }

    static class A {
        void test(a) {
            System.out.println("test");
        }

        void test1(a) {
            System.out.println("test1"); }}static class B {
        private A a;

        public void setA(A a) {
            this.a = a;
        }

        void test(a) { a.test(); }}}Copy the code

Summary: Consider composition/aggregation first and inheritance last. Aggregate composition is a “black box” reuse, whereas inheritance is a white box, transparent to subclasses.

There are three ways in which dependencies can be passed

  • As interface
  • Constructor pass
  • Setter pass

As interface

package com.wangscaler.dependencytransfer;

/ * * *@author wangscaler
 * @date2021.06.17 immediately * /
public class DependencyTransfer {
    public static void main(String[] args) {
        Driver driver = new Driver();
        driver.drive(new Civic());
    }

    interface IDriver {
        void drive(ICar car);
    }

    interface ICar {
        void running(a);
    }

    static class Civic implements ICar {

        public void running(a) {
            System.out.println("Civic seconds day seconds earth seconds air."); }}static class Driver implements IDriver {

        public void drive(ICar car) { car.running(); }}}Copy the code

In this case, we pass ICar in the interface IDriver, and the Driver implements IDriver to get the running functionality of the car

Constructor pass

package com.wangscaler.dependencytransfer;

/ * * *@author wangscaler
 * @date2021.06.17 immediately * /
public class DependencyTransfer1 {
    public static void main(String[] args) {
        Driver driver = new Driver(new Civic());
        driver.drive();
    }

    interface IDriver {
        void drive(a);
    }

    interface ICar {
        void running(a);
    }

    static class Civic implements ICar {

        public void running(a) {
            System.out.println("Civic seconds day seconds earth seconds air."); }}static class Driver implements IDriver {
        public ICar car;

        public Driver(ICar car) {
            this.car = car;
        }

        public void drive(a) { car.running(); }}}Copy the code

Instead of interface passing, Icar is retrieved through the constructor as a member variable of the Driver.

Setter pass

package com.wangscaler.dependencytransfer;

/ * * *@author wangscaler
 * @date2021.06.17 immediately * /
public class DependencyTransfer2 {
    public static void main(String[] args) {
        Driver driver = new Driver();
        driver.setCar(new Civic());
        driver.drive();
    }

    interface IDriver {

        void drive(a);

    }

    interface ICar {
        void running(a);
    }

    static class Civic implements ICar {

        public void running(a) {
            System.out.println("Civic seconds day seconds earth seconds air."); }}static class Driver implements IDriver {
        public ICar car;

        public void drive(a) {
            car.running();
        }

        public void setCar(ICar car) {
            this.car = car; }}}Copy the code

For the member variable ICar, pass in the Setter method.

Section extra words: don't recruit black, my civic domain is second day second to second air.

conclusion

That brings us to our seven principles, the three core principles of design: 1. Identify possible changes and extract them. Second, for the interface programming, focus on abstraction rather than concrete. Loose coupling. To borrow a word from Language Chinese: Access restrictions, functions should be frugal, dependencies should not be allowed, dynamic interface, superclass should be abstract, extension does not change just learn these concepts, it is difficult to use flexibly, see this you may think you have learned, maybe you think you have learned nothing, practice is the real knowledge. Follow along with my design Patterns column to see how design patterns actually apply these principles, and you may have a good idea.