1.概要
2.内容
当前:单件+抽象工厂+创建者+工厂方法
需求:坦克大战
创建两种坦克
坦克类型 | 射程 | 速度 |
b70 | 70米 | 时/70公里 |
b50 | 50米 | 时/50公里 |
设计说明
1.抽象工厂(AbstractFActory)承担了创建部件的任务
2.创建者(IBuilder)承担了讲部件组装的任务
3.工厂方法(IFactory)类相当于创建者模式的导演,但是他是并未给用户提供选择创建者的接口。
而是通过自己的多态来实现加载不同的创建者。
类图
代码
//-------功能类-------------------
//功能基类
class Function{
public String mOperation;
public void exe(int type) {
System.out.println(mOperation+type);
}
};
//射击类
class ShotFun extends Function{
static ShotFun mFunction = new ShotFun();
static ShotFun get() {
return mFunction;
}
public ShotFun() {
mOperation = "射击:";
}
}
//行走类
class RunFun extends Function{
static RunFun mFunction = new RunFun();
static RunFun get() {
return mFunction;
}
public RunFun() {
mOperation = "跑:";
}
}
//====== interface 接口和抽象类 ========================
interface ITank{
void shot();
void run();
void setmShot(IOperation mShot);
void setmRun(IOperation mRun);
}
interface IOperation{
void exe();
}
interface IAbstractFactory{
IOperation createShot();
IOperation createRun();
}
interface IBuilder{
//给坦克安装发射功能
void createShout(ITank t);
//给坦克安装行走
void createRun(ITank t);
}
interface IFactory{
ITank createTank();
}
//====== 实装类如下 ========================
//------功能类-----------------------------
//70的发射功能
class Shot70 implements IOperation{
public void exe() {
ShotFun.get().exe(70);
}
}
//70的行走功能
class Run70 implements IOperation{
public void exe() {
RunFun.get().exe(70);
}
}
//50的发射功能
class Shot50 implements IOperation{
public void exe() {
ShotFun.get().exe(50);
}
}
//50的行走功能
class Run50 implements IOperation{
public void exe() {
RunFun.get().exe(50);
}
}
class Tank implements ITank{
IOperation mShot;
IOperation mRun;
int mSubType;
public void setmSubType(int mSubType) {
this.mSubType = mSubType;
}
public void setmShot(IOperation mShot) {
this.mShot = mShot;
}
public void setmRun(IOperation mRun) {
this.mRun = mRun;
}
public void shot() {
mShot.exe();
}
public void run() {
mRun.exe();
}
}
//---------抽象工------------------------------------------
//抽象工厂-70
class AbstractFactory70 implements IAbstractFactory{
public IOperation createShot() {
return new Shot70();
}
public IOperation createRun() {
return new Run70();
}
}
//抽象工厂-50
class AbstractFactory50 implements IAbstractFactory{
public IOperation createShot() {
return new Shot50();
}
public IOperation createRun() {
return new Run50();
}
}
//---------------创建者-----------------------------------
//创建者
abstract class Builder implements IBuilder{
IAbstractFactory mIAbstractFactory;
public void createShout(ITank t) {
t.setmShot(mIAbstractFactory.createShot());
}
public void createRun(ITank t) {
t.setmRun(mIAbstractFactory.createRun());
}
}
//创建者-70
class Builder70 extends Builder{
public Builder70() {
mIAbstractFactory = new AbstractFactory70();
}
}
//创建者-50
class Builder50 extends Builder{
public Builder50() {
mIAbstractFactory = new AbstractFactory50();
}
}
//----------工厂方法------------------------------------------
//工厂方法
abstract class Factory implements IFactory{
IBuilder mBuilder;
public ITank createTank() {
ITank t = new Tank();
mBuilder.createRun(t);
mBuilder.createShout(t);
return t;
}
}
//工厂方法-70
class Factory70 extends Factory{
public Factory70() {
mBuilder = new Builder70();
}
}
//工厂方法-50
class Factory50 extends Factory{
public Factory50() {
mBuilder = new Builder50();
}
}
//主程序入口
public class Client {
public static void main(String[] args) {
System.out.println("hello worldff !");
Factory70 f7 = new Factory70();
ITank t = f7.createTank();
t.shot();
t.run();
}
}
运行结果
下一篇:一个实例用全创建型模式-优化(冗余消除)-优快云博客
3.关联链接
4.关联知识
1.建型模式对比说明
以下是创建型设计模式的对比表格,基于权威资料整理,涵盖核心特征与适用场景:
模式名称 | 意图 | 结构关键点 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|
单例模式 | 确保类只有一个实例,提供全局访问点 | 私有构造函数、静态实例变量、公有静态获取方法(如getInstance() ) | 节省内存,避免资源多重占用,如配置管理、线程池 | 扩展困难,违背开闭原则,线程安全问题(需同步机制) | 需唯一实例的场景(如日志记录、数据库连接池) |
工厂方法模式 | 定义创建对象的接口,由子类决定实例化类 | 抽象产品、具体产品、抽象工厂、具体工厂(子类实现工厂方法) | 符合开闭原则,扩展性好,支持多产品系列 | 新增产品需新增工厂类,增加系统复杂度 | 需灵活扩展产品家族的场景(如跨平台组件、插件系统) |
抽象工厂模式 | 提供创建一系列相关或依赖对象的接口 | 抽象工厂、具体工厂、抽象产品族、具体产品族 | 管理产品族,保持产品一致性,如跨平台UI组件 | 新增产品族需修改工厂接口,违反开闭原则 | 需跨平台/跨主题组件的场景(如迷宫游戏中魔法与正常组件切换) |
建造者模式 | 分步构建复杂对象,解耦构造过程与表示 | 产品类、抽象建造者、具体建造者、指挥者(Director) | 支持多配置,代码清晰,如复杂对象组装(电脑配置、房屋装修) | 代码量增加,需维护Builder类 | 构建过程复杂且需不同表示的场景(如游戏角色技能组合、汽车定制) |
原型模式 | 通过复制现有对象创建新实例,避免重复初始化 | 抽象原型(Cloneable 接口)、具体原型(实现clone() 方法)、客户端调用克隆 | 性能高效(尤其深克隆),避免复杂构造过程 | 需实现克隆逻辑,浅克隆可能共享引用对象 | 创建成本高的对象(如复杂配置、图形对象、文档对象) |
关键对比总结:
- 实例控制:单例模式严格限制实例数量,其他模式关注对象创建方式。
- 扩展性:工厂方法与抽象工厂通过接口解耦,建造者与原型通过配置或克隆灵活扩展。
- 复杂度:建造者模式适合多步骤构造,原型模式简化高成本对象创建。
- 适用场景:
- 单例:资源管理(如连接池)。
- 工厂方法:产品线扩展(如插件系统)。
- 抽象工厂:跨平台组件(如UI主题)。
- 建造者:复杂对象组装(如游戏角色)。
- 原型:对象克隆(如配置快照)。
此表格整合了权威资料中的定义、结构图及案例,确保信息准确且实用。
2.应用举例 - python
以下是基于坦克大战需求的创建型设计模式应用举例,结合公共需求与模式特性展开:
1. 工厂方法模式 (Factory Method)
需求扩展:支持未来新增坦克类型(如90式坦克)。
实现逻辑:
- 定义抽象工厂接口
TankFactory
,由具体子类(如Type70Factory
、Type50Factory
)实现创建方法。 - 客户端通过工厂子类创建对应坦克,无需关心具体实现。
from abc import ABC, abstractmethod
class Tank(ABC):
@abstractmethod
def move(self): pass
@abstractmethod
def fire(self): pass
class Type70Tank(Tank):
def move(self): print("70式坦克以70km/h移动")
def fire(self): print("发射7公里射程炮弹")
class Type50Tank(Tank):
def move(self): print("50式坦克以50km/h移动")
def fire(self): print("发射5公里射程炮弹")
class TankFactory(ABC):
@abstractmethod
def create_tank(self): pass
class Type70Factory(TankFactory):
def create_tank(self): return Type70Tank()
class Type50Factory(TankFactory):
def create_tank(self): return Type50Tank()
# 客户端
factory = Type70Factory()
tank = factory.create_tank()
tank.move() # 输出: 70式坦克以70km/h移动
对比点:
- 扩展性:新增
Type90Factory
即可支持新坦克,无需修改客户端代码。 - 适用场景:需灵活扩展产品家族(如跨平台组件)。
2. 抽象工厂模式 (Abstract Factory)
需求扩展:坦克需配套特定炮弹类型(如70式用穿甲弹,50式用高爆弹)。
实现逻辑:
- 定义抽象工厂接口
TankFactory
,包含创建坦克和炮弹的方法。 - 具体工厂(如
Type70Factory
)同时生成坦克和配套炮弹,确保一致性。
class Bullet(ABC):
@abstractmethod
def explode(self): pass
class ArmorPiercingBullet(Bullet): # 穿甲弹
def explode(self): print("穿甲弹爆炸")
class HEBullet(Bullet): # 高爆弹
def explode(self): print("高爆弹爆炸")
class AbstractTankFactory(ABC):
@abstractmethod
def create_tank(self) -> Tank: pass
@abstractmethod
def create_bullet(self) -> Bullet: pass
class Type70Factory(AbstractTankFactory):
def create_tank(self): return Type70Tank()
def create_bullet(self): return ArmorPiercingBullet()
class Type50Factory(AbstractTankFactory):
def create_tank(self): return Type50Tank()
def create_bullet(self): return HEBullet()
# 客户端
factory = Type70Factory()
tank = factory.create_tank()
bullet = factory.create_bullet()
tank.fire() # 输出: 发射7公里射程炮弹
bullet.explode() # 输出: 穿甲弹爆炸
对比点:
- 产品族管理:确保坦克与炮弹的兼容性(如70式只能用穿甲弹)。
- 适用场景:需跨平台/跨主题组件(如迷宫游戏中魔法与正常组件切换)。
3. 建造者模式 (Builder)
需求扩展:坦克支持自定义配置(如迷彩涂装、增强装甲)。
实现逻辑:
- 将坦克构建过程分解为多个步骤(基础属性、外观、防御),由指挥者(Director)控制流程。
- 客户端可通过不同建造者生成个性化坦克。
class TankBuilder(ABC):
@abstractmethod
def add_engine(self): pass
@abstractmethod
def add_armor(self): pass
@abstractmethod
def add_camouflage(self): pass
class Type70Builder(TankBuilder):
def __init__(self):
self.tank = Type70Tank()
def add_engine(self):
self.tank.engine = "高功率引擎"
return self
def add_armor(self):
self.tank.armor = "复合装甲"
return self
def add_camouflage(self):
self.tank.camouflage = "丛林迷彩"
return self
class Director:
def construct(self, builder):
return builder.add_engine().add_armor().add_camouflage().tank
# 客户端
director = Director()
builder = Type70Builder()
tank = director.construct(builder)
print(tank.engine) # 输出: 高功率引擎
对比点:
- 构建灵活性:支持多配置选项(如选择迷彩或装甲类型)。
- 适用场景:构建过程复杂且需不同表示(如游戏角色技能组合)。
4. 原型模式 (Prototype)
需求扩展:快速克隆已有坦克并调整属性(如生成敌方AI坦克)。
实现逻辑:
- 通过克隆现有坦克实例创建新对象,避免重复初始化。
- 可修改克隆体的属性(如射程、速度)。
import copy
class TankPrototype:
def __init__(self, speed, range):
self.speed = speed
self.range = range
def clone(self):
return copy.deepcopy(self)
# 创建原型
prototype_70 = TankPrototype(70, 7)
prototype_50 = TankPrototype(50, 5)
# 克隆并调整属性
enemy_tank = prototype_70.clone()
enemy_tank.speed = 65 # AI坦克减速
print(enemy_tank.speed) # 输出: 65
对比点:
- 性能优化:避免重复构造复杂对象(如配置快照)。
- 适用场景:创建成本高的对象(如复杂图形、文档)。
5. 单例模式 (Singleton)
需求扩展:全局管理所有坦克实例(如战场中的唯一ID分配)。
实现逻辑:
- 确保坦克工厂或注册表为全局唯一实例,避免资源冲突。
class TankRegistry:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super().__new__(cls)
cls._instance.tanks = {}
return cls._instance
# 客户端
registry1 = TankRegistry()
registry2 = TankRegistry()
print(registry1 is registry2) # 输出: True
对比点:
- 全局控制:管理共享资源(如唯一ID池、全局配置)。
- 适用场景:需唯一实例的场景(如日志记录、线程池)。
模式对比总结
模式 | 核心特性 | 坦克需求适配 |
---|---|---|
工厂方法 | 子类决定创建对象 | 灵活扩展坦克类型(如90式) |
抽象工厂 | 创建产品族(坦克+炮弹) | 确保配套组件一致性(70式+穿甲弹) |
建造者 | 分步构建复杂对象 | 自定义配置(迷彩、装甲) |
原型 | 克隆避免重复构造 | 快速生成敌方AI坦克 |
单例 | 全局唯一实例 | 管理坦克注册表或全局配置 |
通过扩展需求(如炮弹类型、自定义配置),各模式的应用场景和优势更加清晰,便于对比理解。
3.应用举例-java
以下是根据坦克大战需求,使用不同创建型模式的Java实现示例及对比说明:
// 公共需求基类
interface Tank {
void fire();
void run();
}
// 具体坦克类型
class Type70Tank implements Tank {
private int speed = 70;
private int range = 7;
@Override
public void fire() { System.out.println("70式发射7公里炮弹"); }
@Override
public void run() { System.out.println("70式以70km/h前进"); }
}
class Type50Tank implements Tank {
private int speed = 50;
private int range = 5;
@Override
public void fire() { System.out.println("50式发射5公里炮弹"); }
@Override
public void run() { System.out.println("50式以50km/h前进"); }
}
// 1. 工厂方法模式(扩展需求:新增坦克类型)
interface TankFactory {
Tank createTank();
}
class Type70Factory implements TankFactory {
@Override
public Tank createTank() { return new Type70Tank(); }
}
class Type50Factory implements TankFactory {
@Override
public Tank createTank() { return new Type50Tank(); }
}
// 2. 抽象工厂模式(扩展需求:配套炮弹类型)
interface Bullet { void explode(); }
class ArmorPiercingBullet implements Bullet { public void explode() {}} // 穿甲弹
class HEBullet implements Bullet { public void explode() {}} // 高爆弹
interface AbstractTankFactory {
Tank createTank();
Bullet createBullet();
}
class Type70AbstractFactory implements AbstractTankFactory {
public Tank createTank() { return new Type70Tank(); }
public Bullet createBullet() { return new ArmorPiercingBullet(); }
}
// 3. 建造者模式(扩展需求:自定义配置)
class TankBuilder {
private int speed;
private int range;
public TankBuilder setSpeed(int speed) {
this.speed = speed;
return this;
}
public TankBuilder setRange(int range) {
this.range = range;
return this;
}
public Type70Tank buildType70() {
Type70Tank tank = new Type70Tank();
// 通过反射设置字段(实际开发建议用setter方法)
try {
Field speedField = Type70Tank.class.getDeclaredField("speed");
speedField.setAccessible(true);
speedField.set(tank, this.speed);
} catch (Exception e) { e.printStackTrace(); }
return tank;
}
}
// 4. 原型模式(扩展需求:克隆并修改属性)
class PrototypeTank implements Cloneable {
private int speed;
private int range;
public PrototypeTank(int speed, int range) {
this.speed = speed;
this.range = range;
}
@Override
protected PrototypeTank clone() throws CloneNotSupportedException {
return (PrototypeTank) super.clone();
}
// 添加设置方法
public void setSpeed(int speed) { this.speed = speed; }
}
// 5. 单例模式(扩展需求:全局唯一工厂)
class SingletonTankFactory {
private static SingletonTankFactory instance;
private SingletonTankFactory() {}
public static synchronized SingletonTankFactory getInstance() {
if (instance == null) {
instance = new SingletonTankFactory();
}
return instance;
}
public Tank createTank(String type) {
return switch (type) {
case "70" -> new Type70Tank();
case "50" -> new Type50Tank();
default -> throw new IllegalArgumentException();
};
}
}
// 使用示例
public class Main {
public static void main(String[] args) throws Exception {
// 工厂方法
TankFactory factory70 = new Type70Factory();
Tank tank1 = factory70.createTank();
// 抽象工厂
AbstractTankFactory abstractFactory = new Type70AbstractFactory();
Bullet bullet = abstractFactory.createBullet();
// 建造者模式
Type70Tank customTank = new TankBuilder().setSpeed(80).buildType70();
// 原型模式
PrototypeTank prototype = new PrototypeTank(70, 7);
PrototypeTank clone = prototype.clone();
clone.setSpeed(65);
// 单例模式
Tank tank2 = SingletonTankFactory.getInstance().createTank("50");
}
}
创建型模式对比说明:
模式 | 核心特点 | 坦克需求适配场景 | 优点 | 缺点 |
---|---|---|---|---|
工厂方法 | 子类决定实例化类型 | 扩展新坦克类型(如Type90) | 符合开闭原则,扩展性好 | 每新增类型需增加工厂类 |
抽象工厂 | 创建相关对象族 | 配套创建坦克+炮弹 | 保证产品族一致性 | 增加新产品族需修改接口 |
建造者 | 分步构建复杂对象 | 自定义坦克配置(速度/射程) | 构建过程透明,可复用配置 | 需要额外建造者类 |
原型 | 克隆现有对象 | 快速生成相似坦克(敌方AI克隆) | 避免重复初始化,性能高 | 深克隆实现复杂 |
单例 | 全局唯一实例 | 统一管理坦克生成规则 | 控制资源访问,保证唯一性 | 可能导致代码耦合 |
模式选择建议:
- 需要灵活扩展坦克类型 → 工厂方法
- 需要配套创建坦克+弹药 → 抽象工厂
- 需要复杂配置的坦克 → 建造者
- 需要快速复制相似对象 → 原型
- 需要全局统一管理 → 单例
(注:实际开发中这些模式可以组合使用,例如用抽象工厂管理不同国家坦克系列,用建造者定制具体型号配置)
4.应用举例-c++
以下是用C++实现的坦克大战创建型模式示例,包含5种模式的对比实现:
#include <iostream>
#include <memory>
#include <unordered_map>
// 公共需求基类
class Tank {
public:
virtual void fire() = 0;
virtual void run() = 0;
virtual ~Tank() = default;
};
// 具体坦克类型
class Type70Tank : public Tank {
public:
void fire() override { std::cout << "70式发射7公里炮弹\n"; }
void run() override { std::cout << "70式以70km/h前进\n"; }
};
class Type50Tank : public Tank {
public:
void fire() override { std::cout << "50式发射5公里炮弹\n"; }
void run() override { std::cout << "50式以50km/h前进\n"; }
};
/*----------------- 1.工厂方法模式 -----------------*/
class TankFactory {
public:
virtual std::unique_ptr<Tank> createTank() = 0;
virtual ~TankFactory() = default;
};
class Type70Factory : public TankFactory {
public:
std::unique_ptr<Tank> createTank() override {
return std::make_unique<Type70Tank>();
}
};
class Type50Factory : public TankFactory {
public:
std::unique_ptr<Tank> createTank() override {
return std::make_unique<Type50Tank>();
}
};
/*----------------- 2.抽象工厂模式 -----------------*/
class Bullet {
public:
virtual void explode() = 0;
virtual ~Bullet() = default;
};
class ArmorPiercingBullet : public Bullet { // 穿甲弹
public:
void explode() override { std::cout << "穿甲弹爆炸\n"; }
};
class HEBullet : public Bullet { // 高爆弹
public:
void explode() override { std::cout << "高爆弹爆炸\n"; }
};
class AbstractTankFactory {
public:
virtual std::unique_ptr<Tank> createTank() = 0;
virtual std::unique_ptr<Bullet> createBullet() = 0;
virtual ~AbstractTankFactory() = default;
};
class Type70AbstractFactory : public AbstractTankFactory {
public:
std::unique_ptr<Tank> createTank() override {
return std::make_unique<Type70Tank>();
}
std::unique_ptr<Bullet> createBullet() override {
return std::make_unique<ArmorPiercingBullet>();
}
};
/*----------------- 3.建造者模式 -----------------*/
class TankBuilder {
public:
TankBuilder& setSpeed(int speed) {
speed_ = speed;
return *this;
}
TankBuilder& setRange(int range) {
range_ = range;
return *this;
}
std::unique_ptr<Type70Tank> buildType70() {
auto tank = std::make_unique<Type70Tank>();
// 通过友元类设置私有成员(实际开发建议用setter)
tank->speed = speed_;
tank->range = range_;
return tank;
}
private:
int speed_ = 70;
int range_ = 7;
};
/*----------------- 4.原型模式 -----------------*/
class PrototypeTank {
public:
virtual ~PrototypeTank() = default;
virtual std::unique_ptr<PrototypeTank> clone() = 0;
void setSpeed(int speed) { speed_ = speed; }
void setRange(int range) { range_ = range; }
protected:
int speed_;
int range_;
};
class ConcretePrototype : public PrototypeTank {
public:
std::unique_ptr<PrototypeTank> clone() override {
return std::make_unique<ConcretePrototype>(*this);
}
};
/*----------------- 5.单例模式 -----------------*/
class SingletonTankFactory {
public:
static SingletonTankFactory& getInstance() {
static SingletonTankFactory instance;
return instance;
}
std::unique_ptr<Tank> createTank(const std::string& type) {
if (type == "70") return std::make_unique<Type70Tank>();
if (type == "50") return std::make_unique<Type50Tank>();
return nullptr;
}
private:
SingletonTankFactory() = default;
};
/*----------------- 使用示例 -----------------*/
int main() {
// 工厂方法
Type70Factory factory70;
auto tank1 = factory70.createTank();
tank1->run();
// 抽象工厂
Type70AbstractFactory abstractFactory;
auto bullet = abstractFactory.createBullet();
bullet->explode();
// 建造者模式
auto customTank = TankBuilder().setSpeed(80).buildType70();
customTank->run();
// 原型模式
ConcretePrototype proto;
proto.setSpeed(65);
auto clone = proto.clone();
// 单例模式
auto& singleton = SingletonTankFactory::getInstance();
auto tank2 = singleton.createTank("50");
tank2->fire();
return 0;
}
创建型模式对比表格:
模式 | 核心特点 | 坦克需求适配场景 | 优点 | 缺点 |
---|---|---|---|---|
工厂方法 | 子类决定实例化类型 | 扩展新坦克类型(如Type90) | 符合开闭原则,扩展性好 | 每新增类型需增加工厂类 |
抽象工厂 | 创建相关对象族 | 配套创建坦克+炮弹 | 保证产品族一致性 | 增加新产品族需修改接口 |
建造者 | 分步构建复杂对象 | 自定义坦克配置(速度/射程) | 构建过程透明,可复用配置 | 需要额外建造者类 |
原型 | 克隆现有对象 | 快速生成相似对象(敌方AI克隆) | 避免重复初始化,性能高 | 深克隆实现复杂 |
单例 | 全局唯一实例 | 统一管理坦克生成规则 | 控制资源访问,保证唯一性 | 可能导致代码耦合 |
模式选择建议:
- 工厂方法:适合需要灵活扩展坦克类型的场景
- 抽象工厂:适合需要配套创建坦克和弹药的场景
- 建造者:适合需要复杂配置的定制坦克
- 原型:适合需要快速复制相似对象的场景
- 单例:适合需要全局统一管理坦克生成的场景
(注:实际开发中这些模式可以组合使用,例如用抽象工厂管理不同国家坦克系列,用建造者定制具体型号配置)