We all know that there are five principles of design patternsCopy the code
  1. Single responsibility principle: Implementation classes should have a single responsibility.
  2. Open closed principle: Open for extensions, closed for modifications.
  3. Richter’s substitution rule: Don’t break the inheritance system.
  4. Interface isolation principle: Keep interfaces simple and simple when designing them.
  5. The dependency inversion principle: Program to the interface.

The five principles of the design pattern are understood, because the simple factory pattern uses factories to return the desired instantiated objects, whereas the factory method uses object factories after the interface is implemented to return the instantiated objects. The first two have certain disadvantages

  1. Simple factory mode (static factory mode) : violated the open and close principle, high coupling degree
  2. Factory method pattern: Belongs to the polymorphic factory pattern, defines the factory interface to create product objects, postponing the actual creation to the subclass, but the object creation logic appears in the call class, which violates the single responsibility principle and increases the complexity of project development

Abstract Factory pattern

Product interfaces and implementation classes

public interface Engine {  // Example engine, others omitted

    void run(a);
}

class HighEndEngine implements Engine {

    @Override
    public void run(a) {
        System.out.println("High-end engine, quick start."); }}class LowEndEngine implements Engine {
    @Override
    public void run(a) {
        System.out.println("Low end engine, slow start."); }}Copy the code

Factory interface

public interface CarFactory {

    Engine createEngine(a);
    
    Tyre createTyre(a);
    
    Seat createSeat(a);
}
Copy the code

Factory implementation class

public class HighEndCarFactory implements CarFactory {

    @Override
    public Engine createEngine(a) {
        return new HighEndEngine();
    }

    @Override
    public Tyre createTyre(a) {
        return new HighEndTyre();
    }

    @Override
    public Seat createSeat(a) {
        return newHighEndSeat(); }}public class LowEndCarFactory implements CarFactory {

    @Override
    public Engine createEngine(a) {
        return new LowEndEngine();
    }

    @Override
    public Tyre createTyre(a) {
        return new LowEndTyre();
    }

    @Override
    public Seat createSeat(a) {
        return newLowEndSeat(); }}Copy the code

Client call

public class Client {

    public static void main(String[] args) {
        CarFactory cf = newHighEndCarFactory(); Engine engine = cf.createEngine(); Tyre tyre = cf.createTyre(); Seat seat = cf.createSeat(); }}Copy the code

It is simple to understand that high-end factories only produce high-end products, such as high-end engines, high-end tires and high-end seats. When several new products are added to the product family, it is only necessary to create product classes and add corresponding methods to corresponding factory classes.

conclusion

There are five principles and one law that are hard to follow when using design patterns. We use design patterns to make our code reusable, extensible, and flexible. We can’t just stick to these rules and limit our programming imagination and play. Therefore, the choice of design patterns needs to be weighed against the actual needs of the project. It’s like our three database paradigms. It’s hard to follow all three paradigms in the same way, sometimes adding a bit of data redundancy for the sake of performance and efficiency like queries.