设计模式——Factory Method

本文详细介绍了工厂方法设计模式的概念、作用及应用场景,并通过代码示例展示了如何利用该模式实现对象创建过程的解耦。

Factory Mothod的中文名:工厂方法

作用

GOF中的描述:定义一个用于创建对象的接口,让子类决定实例化哪一类。Factory Method使一个类的实例化延迟到子类。

描述的解释:

  1. 创建:解除对类型的硬编码,使其支持可扩展的类型。
  2. 使用:手动给定类的类型,将对应的子类实例化。

优缺点

  1. 不绑定特定的类,支持进行功能扩展;
  2. 隔离了变化的部分——创建都在统一的函数中,且创建函数的实现可自行更改;
  3. 使用上稍微不方便,因类多,需要结合选择的参数,再去实例化哪个具体类;

结构

 Product只负责产生具体的产品,具体的生产过程在ConcreteProduct中自行定义。而创建产品所需的组件的由Creator来确定。

例子

以上图为例,下面的代码中,Room、Door、Wall表示基本元素。Product指代MazeGame,ConcreteProduct指代EnchantedMaeGame、BombedMaeGame。Creator中的FactoryMethod,通过MazeGame中的4个虚函数表示,而ConcreteCreator则是EnchantedMazeGame中的MakeRoom、MakeDoor方法,BombedMazeGame中的MakeWall、MakeRoom方法。

// Maze.h
#pragma once

class Room {
public:
    Room(int n) { }
};
class Wall {};

class Door {
public:
    Door(Room* r1, Room* r2) {}
};

class Maze {
public:
    void AddRoom(Room* r1) {}
};

/////////////////////////////////////////////////////////////////
class EnhantedRoom : public Room {
public:
    EnhantedRoom(int n) : Room(n) {
    }
};

class DoorNeedingSpell : public Door {
public:
    DoorNeedingSpell(Room* r1, Room* r2) : Door(r1, r2) { }
};

class BombedWall : public Wall {};

class BombedRoom : public Room {
public:
    BombedRoom(int n) : Room(n) {}
};
// MazeGame.h
#pragma once
#include "Maze.h"

class MazeGame {
public:
	MazeGame() {}
	Maze* CreateMaze()
	{
		Maze* aMaze = MakeMaze();

		Room* r1 = MakeRoom(1);
		Room* r2 = MakeRoom(2);
		Door* door = MakeDoor(r1, r2);

		aMaze->AddRoom(r1);
		aMaze->AddRoom(r2);

		// ...

		return aMaze;
	}

    // factory method
	virtual Maze* MakeMaze() const { return new Maze(); }
	virtual Wall* MakeWall() const { return new Wall; }
	virtual Room* MakeRoom(int n) const { return new Room(n); }
	virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); }
};

// 不同实现
class EnchantedMazeGame : public MazeGame {
public:
	EnchantedMazeGame() {}

	// Differ with Maze Factory
	virtual Room* MakeRoom(int n) const { return new EnhantedRoom(n); }
	virtual Door* MakeDoor(Room* r1, Room* r2) const { return new DoorNeedingSpell(r1, r2); }
};

class BombedMazeGame : public MazeGame {
public:
	BombedMazeGame() {}

	virtual Wall* MakeWall() const { return new BombedWall; }
	virtual Room* MakeRoom(int n) const { return new BombedRoom(n); }
};

 

// main.cpp
#include <iostream>

/////////////////////////////////////////////////////////////////
#include "MazeGame.h"

int main()
{
    {
        MazeGame* game = new MazeGame();
        Maze* aMaze = game->CreateMaze(); 
    }

    {
        MazeGame* game = new EnchantedMazeGame();
        Maze* aMaze = game->CreateMaze();
    }

    {
        MazeGame* game = new BombedMazeGame();
        Maze* aMaze = game->CreateMaze();
    }
}

Github连接:https://github.com/potterhere/CS-note/tree/master/DesignPattern/CreateMode_FactoryMethod

相关模式

抽象工厂(Abstract Factory)。

抽象工厂和工厂方法两者之间很相似,不同的地方在于抽象工厂中,抽象工厂指提供类似于集团总部提供的指导思想或者框架,具体的执行归下面的子公司负责。换个说法来说,抽象工厂提取出了抽象的接口部分,这个部分需要在早期设计中实现。而工厂方法中,只要求其能提供所需的组件即可。

参考资料

1. 《设计模式:可复用面向对象软件的基础》 GOF

2.  抽象工厂——Youtube

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值