c++解耦:Factory Method

讨论C++语言中如何将通用逻辑与使用到的频繁变化的具体类型解耦。

假设存在以下设计:

/* ================================================================== */
#include <iostream>

class Core {
public:
    ~Core(){}
public:
    void solve(){
        std::cout << "Core->solve" << std::endl;
    }   
};

class Processor {
public:
    ~Processor(){}
public:
    void run() {
        // ...
        Core * core = new Core();
        core->solve();
        // ...
        delete core;
    }   
};

/* ================================================================== */
// 外部调用
void callback() {
    Processor * processor = new Processor();
    processor->run();
    delete processor;
}

业务上每处理一个外部调用,都会创建Processor对象,执行处理流程run,执行流程会创建内部依赖类Core的对象。run流程通用稳定,外部存在多种类型的调用,Core类型与外部调用强相关。

上述设计存在的问题:

Processor类与特定Core类紧耦合,关系是一对一。业务上Processor类是通用类型逻辑,Core类型又与外部强相关,变化趋势明显。稳定流程引入了变化的动作,当外部调用需求持续扩展,每种调用都需要实现对应的Processor类型,拓展性差。代码明显冗余,复用性差;

可以看到,Processor类的紧耦合是 new Core对象操作引入的(产生了编译时依赖),针对创建对象动作的解耦,讨论使用设计模式领域的FactoryMethod思路求解。

优化思路:复用Processor,为new object动作提供一种封装机制,将依赖具体类型转变为依赖某种创建对象的机制,实现上绕开直接创建对象实现解耦,延迟new动作到运行时;

方案:

  1. 抽象Core类型基类,Processor只依赖稳定的抽象类型指针(面向接口);
  2. 抽象Factory类型基类,提供封装Core类型对象的创建动作的方法,交由具体子类overwrite(虚函数),去创建对应具体Core类型的对象(封装变化);
  3. Processor只持有Factory抽象类型的指针(多态),在创建Processor对象时被初始化为具体Factory(运行时才依赖具体类型)。
/* ================================================================== */
class ICore {
public:
    virtual ~ICore(){}
public:
    virtual void solve()=0;
};

class Factory {
public:
    virtual ICore * createInstance()=0;
    virtual ~Factory(){}
};

class Processor {
public:
	Factory * factory;
public:
	Procrssor(Factory * f){
		this->factory = f
	}
	~Processor(){ delete this->factory; }
public:
	void run() {
		// ...
		ICore * core = this->factory->createInstance();
		core->solve();
		// ...
		delete core;
	}
};

class CoreA : public ICore {
public:
    void solve(){
      	// ...
    }
};

class CoreAFactory : public Factory {
public:
    CoreA * createInstance() {
        return new CoreA();
    }
};

/* ================================================================== */
// 外部调用
void callbackA() {
    CoreAFactory * coreAFactory = new CoreAFactory();
    Processor processor = Processor(coreAFactory);
    processor.run();
}

现在扩展上述场景问题,如果Processor中与外部调用强相关的类型有不止一种,还是按FactoryMethod解耦的思路,讨论下面两种方案的优劣:

  1. 对每种类型封装独立的Factory,Processor中存在多种Factory指针;
  2. 共用Factory,公共Factory统一负责多种类型的实例化,Processor中只存在唯一的Factory指针;

从单一职责角度看,使用多种对象共同协助完成一个流程,可以认为对象之间强相关,这时候将类型交由统一的Factory去负责时合理的。方案1中,假设对Processor实例化时传入负责不同子类型的Factory初始化,从接口实现上看是不安全的,也大概率会引起执行流程错误。

class IAbstractFactory {
public:
  	virtual ICore * createCoreInstance()=0; // 第一种类型
  	virtual IDraw * createDrawInstance()=0; // 第二种类型
  	// ...
};
posted @ 2024-03-23 14:11  linxx-  阅读(10)  评论(0编辑  收藏  举报