First, design mode

1. What is it

Design Pattern is a set of repeatedly used, most people know, classified, summarized code Design experience, the use of Design Pattern in order to reuse the code, make the code easier to understand and ensure the reliability of the code.

In layman’s terms: a project’s code level design architecture, the layout of the code function. Equivalent to a template. These patterns are giants in the software system summed up successful, can achieve maintainability reuse of the design scheme

2,

There are definitely great benefits to using a uniform template. What are they?

  • Design pattern provides a set of common design vocabulary and a common form to facilitate communication between developers, making the design scheme more easy to understand
  • Design patterns enhance the reusability, extensibility and maintainability of the system
  • Make your code easier to read and help others understand your system faster
  • It helps to understand object-oriented thinking more deeply

Two, common design patterns

1. Simple factories
1) structure

  • Factories: Create objects, create internal logic of product instances, not externally aware. External direct calls to create the desired product objects
  • Product: A common method for all objects, that is, a parent class. Internal methods are declared and not defined.
  • Concrete product: Concrete implementation of a common method for a concrete product.
2) Usage scenarios
  • The factory class is responsible for creating fewer objects, so the business logic in the factory method is not too complicated because there are fewer objects to create.
  • The client only knows the parameters passed into the factory class and doesn’t care how the object is created
3) advantages
  • The factory class contains the necessary judgment logic to decide which instance of a product class to create and when. Does the simple factory pattern achieve the separation of object creation and use
4) shortcomings
  • Because the factory class centralizes the creation logic for all products, it is so overloaded that if it does not work properly, the entire system will suffer
  • System expansion is difficult. Once a new product is added, the factory logic needs to be modified. If there are many product types, the factory logic may be too complex, which is not conducive to system expansion and maintenance
5) code

The pen factory needs to produce two kinds of pens, pencil and ballPen, both of which have writing function. Pen factory produces specific product pencils, specific product pencils to achieve writing function

const (
	pencil = iota / / pencil
	ballPen / / a ball-point pen
)

// Stationery factory
type PenFactory struct {}

// New different factory instances, i.e. specific products. (Pencil, ballpoint pen)
func (t *PenFactory) New(typ int) Pen{
	switch typ {
	case pencil:
		return new(Pencil)
	case ballPen:
		return new(BallPen)
	default:
		return nil}}// Product, which declares the public method for all products in the factory, is implemented in specific products
type Pen interface {
	Write()
}

/ / pencil. Specific products
type Pencil struct {}
// A concrete implementation of a public method
func (*Pencil) Write(a) {
	fmt.Println("Pencil Writing")}// Ball-point pen
type BallPen struct {}
// A concrete implementation of a public method
func (*BallPen) Write(a) {
	fmt.Println("BallPen Writing")}func main(a) {
	var factory PenFactory
	pen := factory.New(pencil) // Use a factory to produce a specific product, how to define the specific, users do not feel
	pen.Write()
}
Copy the code
2. Factory method
1) structure

  • Factory: Instead of creating all the concrete product instances in the implementation, declare a create interface and hand over the initialization actions to the concrete factory
  • Concrete factory: A method of implementing a factory that returns an instance of a concrete product
  • Product: A common method for all objects, that is, a parent class. Internal methods are declared and not defined.
  • Concrete product: Created by a concrete factory that implements a superclass method
2) Usage scenarios

In the factory method pattern, the client does not need to know the class name of the specific product class, only the specific factory that corresponds to the specific product object, which is created by the specific factory class.

3) advantages
  • The user only needs to care about the factory for the desired product, not the creation details
  • Polymorphism based on factory roles and product roles
  • When adding new products to the system, it is only necessary to add a specific factory and specific products, and the system has good scalability
4) shortcomings
  • When adding new products, it is necessary to write new concrete product classes and provide corresponding concrete factory classes. The number of classes in the system will increase in pairs, which increases the complexity of the system to a certain extent. More classes need to be compiled and run, which will bring some extra overhead to the system
5) code

The pen factory needs to produce two kinds of pens, pencil and ballPen, both of which have writing function. Pen factory produces specific factory – Pencil factory, pencil factory produces specific products pencils, specific products to achieve writing function

// Factory, New is implemented by specific factory
type PenFactory interface {
	New() Pen
}
// Product, the parent of all specific products
type Pen interface {
	Write()
}

// Specific product, ballpoint pen
type BallPen struct {}
func (*BallPen) Write(a) {
	fmt.Println("BallPen Writing")}// Specific product factory
type BallPenFactory struct {}
func (p *BallPenFactory) New(a) Pen {
    fmt.Println("create BallPen")
	return new(BallPen)
}

// Pencils, specific products
type Pencil struct {}
func (*Pencil) Write(a) {
	fmt.Println("Pencil Writing")}// Specific product factory
type PencilFactory struct {}
func (p *PencilFactory) New(a) Pen {
	fmt.Println("create Pencil")
	return new(Pencil)
}

func main(a) {
	var factory PenFactory
	factory = &PencilFactory{} // Generate a concrete product
	var pen Pen
	pen = factory.New()
	pen.Write()
}
Copy the code
3. Abstract factories
1) structure

This figure is selected from the quoted article, because the drawing is very clear, we use this figure to illustrate

● AbstractFactory: multiple concrete factory methods are declared in an AbstractFactory to create different types of products. As you can see, unlike the factory approach in Section 2, this abstract factory can not only create A concrete product, but also produce A series of product families (A,B,C). This is the abstract factory instance. The concrete factory instance has the interface to create this series of products

  • ConcreteFactory: concrete factories implement abstract factories. Each ConcreteFactory method can return a specific product object. It implements the method of creating products declared in an abstract factory, generating A set of concrete products (A,B,C) that make up A product family

    ● AbstractProduct: it declares interfaces for each product, declaring the business methods that the product has in the AbstractProduct.

    ● concrete products: it defines ConcreteProduct objects produced by concrete factories and implements business methods declared in abstract product interfaces.

2) Usage scenarios

There is more than one product family in the system and only one of them is used at a time.

3) advantages
  • The abstract factory pattern isolates the generation of concrete classes so that customers do not need to know which concrete products are created
  • When multiple objects in a product family are designed to work together, it ensures that clients always use only objects in the same product family
  • It is convenient to add a new product family without modifying the existing system, in accordance with the “open closed principle”
4) shortcomings
  • Adding a new product-level structure is cumbersome, requiring major changes to the existing system and even changes to the abstraction layer code
5) code

The skin library has Spring and Summer styles. Spring style has light green buttons and green text boxes. The Summer style has light blue buttons, light blue text boxes.

// Interface skin Factory interface: Abstract factory
type SkinFactory interface  {
	createButton() Button
	createTextField() TextField
}
// Abstract product 1
type Button interface{
	display();
}
// Abstract product 2
type TextField interface{
	write();
}

// Specific product 1
type SpringButton struct {}
func (s *SpringButton)display(a){
	fmt.Println("SpringButton display")}// Specific product 2
type SpringTextField struct {}
func (s *SpringTextField)write(a){
	fmt.Println("SpringTextField write")}// Specific product 3
type SummerTextField struct {}
func (s *SummerTextField)write(a){
	fmt.Println("SummerTextField write")}// Specific product 4
type SummerButton struct {}
func (s *SummerButton)display(a){
	fmt.Println("SummerButton display")}//Spring skin Factory: specific factory
type SpringSkinFactory struct {}
// Create specific product 1
func (s *SpringSkinFactory) createButton(a) Button {
	return new(SpringButton)
}
// Create product 2
func (s *SpringSkinFactory) createTextField(a) TextField {
	return new(SpringTextField)
}

//Summer Skin Factory: specific factory
type SummerSkinFactory struct {}
// Create specific product 3
func (s *SummerSkinFactory) createButton(a) Button {
	return new(SummerButton)
}
// Create product 4
func (s *SummerSkinFactory) createTextField(a) TextField {
	return new(SummerTextField)
}


func main(a) {
	var skinFactory SkinFactory
	skinFactory = &SummerSkinFactory{} // Create a product family (product 3, product 4)
    but := skinFactory.createButton() // Create a product (product 3)
	but.display()
}

/* C:\Users\Administrator\AppData\Local\Temp\___go_build_xctest2_main.exe #gosetup SummerButton display */
Copy the code
4, single cases
1) structure

Singleton Pattern: Ensures that a class has only one instance and that it instantiates and makes that instance available to the entire system. This class is called a Singleton class, which provides globally accessible methods. Such as database connection, resource configuration.

There are two common patterns: hungry and lazy

  • Hungry mode: Instantiate objects during program initialization, without multithreading concerns. The inside of the golanginitinterface
  • Lazy mode: Singletons are created when they are used for the first time and do not occupy system resources all the time. Lazy loading is implemented, but multiple threads must be accessed at the same time. Consider the problem of creating multiple instances of concurrent calls from multiple threads, requiring mutex. The Golang language is commonly usedsync.onceImplement the slacker model,sync.onceBuilt-in mutex
2) Usage scenarios
  • The system only needs one instance object, if the system requires a unique sequence number generator or resource manager, or if the resource consumption is too high to allow the creation of only one object
3) advantages
  • Since only one object exists in system memory, system resources can be saved, and the singleton pattern can undoubtedly improve system performance for some objects that need to be created and destroyed frequently.
4) shortcomings
  • Singleton classes are too heavy on responsibilities and violate the “single responsibility principle” to some extent. Because the singleton class acts both as a factory, providing factory methods, and as a product, containing business methods that blend the creation of the product with the functionality of the product itself

  • Golang runtime environments provide automatic garbage collection, so if an instantiated shared object is not used for a long time, the system considers it garbage, destroys and recycles the resource, and then re-instantiates it the next time it is used, resulting in a loss of state for the shared singleton

5) code
func main(a) {
	var once sync.Once
	onceBody := func(a) {
		fmt.Println("Only once") // This can be a database connection, initialization, etc
	}
	for i := 0; i < 10; i++ {
		once.Do(onceBody)
	}
}

/*
Only once
*/
Copy the code

reference

  • Wall crack recommended! Design mode complete set