Loading

工厂模式

创建型模式对实例化进行抽象,将对象的创建和使用进行分离。外界只需知道对应的公共接口,不需要知道内部的具体实现细节。符合单一职责原则。

简单工厂模式

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。简单工厂模式包含如下角色:

  • 抽象产品:所有具体产品的父类,负责描述所有实例所共有的公共接口;
  • 具体产品:实际创建的目标对象
  • 工厂:负责实现创建所有实例的内部逻辑。

扩展需注意:添加新产品必须修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

C++代码示例

/**
 * 抽象产品
 */
class Shape {
public:
    virtual void draw() = 0;
};

/**
 * 具体产品:圆形
 */
class Circle : public Shape {
public:
    void draw() {
        cout << "draw a circle" << endl;
    }
};
/**
 * 具体产品:三角形
 */
class Rectangle : public Shape {
public:
    void draw() {
        cout << "draw a rectangle" << endl;
    }
};

/**
 * 工厂:负责实现创建所有实例的内部逻辑
 */
class ShapeFactory {
public:
    Shape * createShape(string name) {
        switch (name) {
            case "circle": return new Circle();
            case "rectangle": return Rectangle();
        }
        return nullptr;
    }
};

Go代码示例

// 抽象产品
type IShape interface {
	draw()
}

// 具体产品:圆形
type Circle struct { }

func (p *Circle) draw() {
	fmt.Println("draw a circle")
}

// 具体产品:三角形
type Rectangle struct { }

func (p *Rectangle) draw() {
	fmt.Println("draw a rectangle")
}

// 工厂
type Factory struct { }

func (p *Factory) create(name string) (IShape, error) {
    // 实例化逻辑
	switch name {
	case "circle":
		return &Circle{}, nil
	case "rectangle":
		return &Rectangle{}, nil
	}
	return nil, errors.New("unsupported name")
}

工厂方法模式

工厂方法模式(Factory Method Pattern)也称工厂模式。工厂方法模式包含以下角色:

  • 抽象产品:所有具体产品的父类,负责描述所有实例所共有的公共接口;
  • 具体产品:实际创建的目标对象
  • 抽象工厂:提供统一的创建产品实例的接口,产品的创建延迟到其子类(具体工厂);
  • 具体工厂:负责具体的某类实例的创建。

工厂方法模式相比于简单工厂模式,将创建实例的内部逻辑由 “工厂” 转移到 “客户端” 。

C++代码示例

/**
 * 抽象产品
 */
class Shape {
    virtual void draw() = 0;
};

/**
 * 具体产品:圆形
 */
class Circle : public Shape {
public:
    void draw() {
        cout << "draw a circle" << endl;
    }
};
/**
 * 具体产品:三角形
 */
class Rectangle : public Shape {
public:
    void draw() {
        cout << "draw a rectangle" << endl;
    }
};

/**
 * 抽象工厂
 */
class Factory {
public:
    virtual Shape * createShape() = 0;
};

/**
 * 具体工厂:圆形工厂
 */
class CircleFactory : Factory {
public:
    Shape * createShape() {
        return new Circle();
    }
};
/**
 * 具体工厂:三角形工厂
 */
class RectangleFactory : Factory {
public:
    Shape * createShape() {
        return new Rectangle();
    }
};

Go代码示例

// 抽象产品
type IShape interface {
	Draw()
}

// 具体产品:圆形
type Circle struct { }

func (p *Circle) Draw() {
	fmt.Println("draw a circle")
}

// 具体产品:三角形
type Rectangle struct { }

func (p *Rectangle) Draw() {
	fmt.Println("draw a rectangle")
}

// 抽象工厂
type IFactory interface {
	CreateShape()
}

// 具体工厂:圆形工厂
type CircleFactory struct {}

func (p *CircleFactory) CreateShape() IShape {
	return &Circle{}
}

// 具体工厂:三角形工厂
type RectangleFactory struct {}

func (p *RectangleFactory) CreateShape() IShape {
	return &Rectangle{}
}

抽象工厂模式

抽象工厂模式包含以下角色:

  • 抽象产品:所有具体产品的父类,负责描述所有实例所共有的公共接口;
  • 具体产品:实际创建的目标对象
  • 抽象工厂:提供统一的创建产品实例的接口,产品的创建延迟到其子类(具体工厂);
  • 具体工厂:负责具体的某类实例的创建。

从角色来看,抽象工厂模式与工厂方法模式一致。两者的区别在于,工厂方法模式中每个具体工厂只创建一类产品对象,若一个工厂需要负责多个类型的实例创建,此时适合使用抽象工厂模式。例如,戴尔工厂负责生产戴尔鼠标、戴尔键盘,惠普工厂负责生产惠普鼠标、惠普键盘。

C++代码示例

/** 抽象产品 **/
class IMouse {
public:
    virtual void use() = 0;
};
class IKeyboard {
public:
    virtual void use() = 0;
};

/** 具体产品 **/
class DellMouse : public IMouse {
public:
    void use() {
        cout << "use Dell mouse" << endl;
    }
};
class DellKeyBoard : public IKeyboard {
public:
    void use() {
        cout << "use Dell keyboard" << endl;
    }
};

class HPMouse : public IMouse {
public:
    void use() {
        cout << "use HP mouse" << endl;
    }
};
class HPKeyBoard : public IKeyboard {
public:
    void use() {
        cout << "use HP keyboard" << endl;
    }
};

/** 抽象工厂 **/
class IFactory {
public:
    virtual IMouse * createMouse() = 0;
    virtual IKeyboard * createKeyboard() = 0;
};

/** 具体工厂 **/
// 戴尔工厂生产戴尔鼠标、戴尔键盘
class DellFactory : public IFactory {
public:
    IMouse * createMouse() {
        return new DellMouse()
    }
    IKeyboard * createKeyboard() {
        return new DellKeyBoard();
    }
};
// 惠普工厂生产惠普鼠标、惠普键盘
class HPFactory : public IFactory {
public:
    IMouse * createMouse() {
        return new HPMouse()
    }
    IKeyboard * createKeyboard() {
        return new HPKeyBoard();
    }
};

Go代码示例

// 抽象产品
type IMouse interface {
	Use()
}
type IKeyboard interface {
	Use()
}

// 具体产品
type DellMouse struct {}
type DellKeyboard struct {}
type HPMouse struct {}
type HPKeyboard struct {}

func (d *DellMouse) Use()  {
	fmt.Println("user Dell mouse")
}
func (d *DellKeyboard) Use()  {
	fmt.Println("use Dell keyboard")
}

func (h *HPMouse) Use()  {
	fmt.Println("use HP mouse")
}
func (h *HPKeyboard) Use() {
	fmt.Println("use HP keyboard")
}

// 抽象工厂
type IFactory interface {
	CreateMouse() IMouse
	CreateKeyboard() IKeyboard
}

// 具体工厂
// 戴尔工厂生产戴尔鼠标、戴尔键盘
type DellFactory struct {}
// 惠普工厂生产惠普鼠标、惠普键盘
type HPFactory struct {}

func (d *DellFactory) CreateMouse() IMouse {
	return &DellMouse{}
}
func (d *DellFactory) CreateKeyboard() IKeyboard {
	return &DellKeyboard{}
}

func (h *HPFactory) CreateMouse() IMouse {
	return &HPMouse{}
}
func (h *HPFactory) CreateKeyboard() IKeyboard {
	return &HPKeyboard{}
}

参考:

posted @ 2021-11-25 19:05  JakeLin  阅读(16)  评论(0编辑  收藏  举报