Abstract Factory
Description:
Creates an instance of several families of classes
Intent
- Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
- A hierarchy that encapsulates: many possible "platforms", and the construction of a suite of "products".
- The new operator considered harmful.
Example:
Note
Idea:
感觉和factory method的区别就是这个有多个不同的factory。
Check list
- Decide if "platform independence" and creation services are the current source of pain.
- Map out a matrix of "platforms" versus "products".
- Define a factory interface that consists of a factory method per product.
- Define a factory derived class for each platform that encapsulates all references to the new operator.
- The client should retire all references to new, and use the factory methods to create the product objects.
Code:
#include <iostream>
#include <vector>
#include <cmath>
#define LINUX
using namespace std;
class Widget{
public:
virtual void draw() = 0;
virtual ~Widget() {} // virtual destructor will call derived class destructor
};
class LinuxButton: public Widget{
public:
void draw() override { cout<<"LinuxButton\n"; }
};
class LinuxMenu: public Widget{
public:
void draw() override { cout<<"LinuxMenu\n"; }
};
class WindowsButton : public Widget {
public:
void draw() { cout << "WindowsButton\n"; }
};
class WindowsMenu : public Widget {
public:
void draw() { cout << "WindowsMenu\n"; }
};
class Factory{
public:
virtual Widget * createButton() = 0;
virtual Widget * createMenu() = 0;
};
class LinuxFactory : public Factory{
public:
Widget * createButton(){
return new LinuxButton;
}
Widget * createMenu(){
return new LinuxMenu;
}
};
class WindowsFactory : public Factory{
public:
Widget * createButton(){
return new WindowsButton;
}
Widget * createMenu(){
return new WindowsMenu;
}
};
class Client{
private:
Factory * factory;
public:
Client(Factory *f): factory(f) {}
void draw(){
Widget *w_b = factory->createButton();
Widget *w_m = factory->createMenu();
w_b->draw();
w_m->draw();
}
};
int main(){
Factory * factory;
#ifdef LINUX
factory = new LinuxFactory;
#else
factory = new WindowsFactory;
#endif
Client *c = new Client(factory);
c->draw();
}