principle:
Single responsibility principle: a class has a single responsibility and only provides one function
Opening and closing principle: class changes are realized by adding code, not modifying the source code; For extension development, close for modification
Dependency Inversion Principle: for interface programming, it depends on abstraction rather than concrete implementation
Creating: how to create objects
Struct: a combination of classes or objects
Behavior: how classes or objects interact
1. Singleton mode
A class can have at most one instance and provides a global access point
Used for: resource management, thread pool and log management
Implementation method:
Class constructor and copy constructor are private, and external construction of instances is prohibited;
The static function is defined in the class to return a unique instance and set it to public
class A{ private: A(){cout<<"Chinese"<<endl;}; A(const A& other); public: static A* aaa(); static A *a; };
1.1 single lazy type
Delay the creation and create when the object is used. Static member variables can only be declared inside the class. Outside the class, nullptr is not initialized first
Lazy, instantiated only when called, non thread safe
A * A::a = nullptr;//Static member variables can only be declared inside the class and initialized outside the class A* A :: aaa(){ if(a == nullptr){ a = new A(); } return a; }
The solution is to lock, but the cost of locking is too high. Locking the read thread is a waste
A* A :: aaa(){ Lock lock; if(a == nullptr){ a = new A(); } return a; }
The solution is to double detect the lock. In case of problems, when the compiler executes new A, the order is unconventional. Normally, 1 opens up space, 2 calls the constructor to initialize the memory, and 3 returns the address to a; If the compiler changes the order of 23 and the first thread comes here, a is not empty. At this time, if thread B comes, it will directly access the memory that does not execute the constructor, and an error will be reported
A* A:: aaa(){ if(a == nullptr){ Lock lock; if(a == nullptr){ a = new A(); } } return a; }
1.2 single case hungry Han style
Direct instantiation, created before the program starts, is thread safe
A * A:: aaa(){ return a; } A * A::a = new A(); //new objects, three parts open up space, call to construct initialization memory and return pointers, so they should be received with pointers
2. Factory
Factories are used to produce products; Is a class that is responsible for creating instances of other classes
2.1 simple factory mode
Simple factory mode is a class responsible for creating instances of other classes. It can return different instances according to different parameters. These instances have a common parent class; All this pattern is responsible for which classes in a large class need instances
Disadvantages: Contrary to the opening and closing principle, the factory class needs to be modified when adding functions. When there are many function classes, the logical structure is complex
Implementation method:
Fruit abstract base class
Specific categories of various fruits
Fruit factory
- An abstract fruit
class friut{ public: virtual void showname() = 0; };
- Two specific fruits
class apple:public friut{ public: void showname(){ cout<<"apple successfully"<<endl; } }; class pear:public friut{ public: void showname(){ cout<<"pear successfully"<<endl; } };
3. A fruit processing plant
class factory{ public: friut* fruit(string f){//Why static if(f == "apple"){ return new apple; } else return new pear; } };
realization
void main() { factory * p = new factory(); friut * apple = p->fruit("apple"); apple->showname(); }
2.2 factory method mode = simple + open close
Define an interface for creating objects, and let subclasses decide which class to instantiate
Avoid creating objects with new. Creating objects with new will depend on specific classes, which cannot be changed later,
Disadvantages: too many classes and high maintenance cost
Implementation method:
A car abstract base class
An abstract base class of automobile factory
Automobile specific category
Specific categories of automobile factory
1. Abstract product automobile
//Abstract product automobile class Car{ public: virtual void carname() = 0; };
2. Plant base class
//Factory base class class CarFactory{ public: virtual Car* carFactoryname() = 0; };
3. Two specific categories of vehicles
//Automobile subclass class Benz:public Car{ public: void carname(){ cout<<"I am Benz"<<endl; } }; class Audi:public Car{ public: void carname(){ cout<<"I am Audi"<<endl; } };
4. Two specific automobile processing plants
//Specific processing plant class BenzFactory:public CarFactory{ public: //Build a Mercedes Car * carFactoryname(){ return new Benz; } }; class AudiFactory:public CarFactory{ public: Car * carFactoryname(){ return new Audi; } };
realization:
void main(){ //The above are all classes. To start building a car, first instance a processing plant CarFactory *factory = nullptr; Car* car = nullptr; factory = new BenzFactory(); //The parent class pointer points to different subclass objects car = factory->carFactoryname(); car->carname(); }
2.3 Abstract Factory
The automobile factory began to build trains in the following ways:
Abstract product automobile
Specific classes
Abstract product train
Specific classes
An abstract processing plant
Specific category of processing plant
//Expand production, automobile + train
//Product A abstract and concrete automobile class Car{ public: virtual void showCarname()=0; }; class BenzCar:public Car{ public: void showCarname(){ cout<< "Car-Benz"<<endl; } }; class AudiCar:public Car{ public: void showCarname(){ cout<< "Car-Audi"<<endl; } };
//Product B Abstract and concrete classes class Train{ public: virtual void showTrainname()=0; }; class BenzTrain:public Train{ public: void showTrainname(){ cout<< "Train-Benz"<<endl; } }; class AudiTrain:public Train{ public: void showTrainname(){ cout<< "Train-Benz"<<endl; } };
//Abstract factory class Factory{ public: virtual Car* carfactory() = 0; virtual Train* Trainfactory() = 0; };
//Specific factory class Benzfactory:public Factory{ public: Car* carfactory() { return new BenzCar; } Train* Trainfactory(){ return new BenzTrain; } }; class Audifactory:public Factory{ public: Car* carfactory() { return new AudiCar; } Train* Trainfactory(){ return new AudiTrain; } };
realization:
void main(){ Car * car = nullptr; Train * train = nullptr; Factory * factory = nullptr; //Mercedes Benz cars and trains factory = new Benzfactory(); car = factory->carfactory(); car->showCarname(); train = factory->Trainfactory(); train->showTrainname(); delete factory; delete car; delete train; //Audi cars and trains factory = new Audifactory(); car = factory->carfactory(); car->showCarname(); train = factory->Trainfactory(); train->showTrainname(); }