c++ - 为什么更喜欢模板方法而不是依赖注入(inject)?

标签 c++ templates dependency-injection software-design

我一直在阅读 Gamma 等人的《设计模式》。与依赖注入(inject)相比,我有一个关于模板方法的问题。

使用模板方法,您可以使用为所需操作或计算提供备选方案的策略“模板化”类。因此,与其从多个备选方案中选择一个策略并将该策略编码到类中,不如让类的用户指定他们想要使用的备选方案。

我觉得这一切都非常合理。但我遇到了一点概念上的障碍。

如果用策略对象实例化一个类,策略对象需要实现一个抽象接口(interface)。然后程序员可以编写不同的策略,所有策略都可以无误地编译到类中,因为策略实现了接口(interface)。使用策略的类被编码到策略接口(interface)而不是实现。

如果您要为这些策略对象定义一个抽象的 IPolicy,为什么不直接使用依赖注入(inject)并在构造时传入 IPolicy

谁能阐明为什么您更喜欢模板方法而不是依赖注入(inject)?

最佳答案

关于“模板方法”(而不是设计模式),以下示例可能有助于确定要做什么的利弊。该示例是创建旨在帮助调试/开发的库的详细模式。

使用模板

struct console_print
{
  static void print(const string& msg) {std::cout<<msg;}
};

struct dont_print
{
  static void print(const string& msg) {}
};

template<printer>
void some_function()
{
  printer::print("some_function called\n");
}

然后图书馆用户可以写:

some_function<console_print>(); //print the verbose message;
some_function<dont_print>();    //don't print any messages.

这段代码的好处是,如果用户不想打印代码,那么对 dont_print::print(msg) 的调用就会从代码中完全消失(空静态类得到轻松优化)。然后可以将此类调试消息输入到性能关键区域。

模板的缺点是你需要在编译之前决定你的策略。您还需要更改任何模板的函数/类签名。

没有模板

以上当然可以用类似的东西来完成:

struct printer 
{
  virtual void print(const std::string& msg) = 0;
}

struct console_print : public printer
{
  void print(const std::string& msg) {std::cout<<msg;}
}
struct debug_print : public printer
{
  void print(const std::string& msg) {}
}

这样做的好处是您可以将打印机类型传递给您的类和函数,并在运行时更改它们(对于某些应用程序可能非常有用)。然而,代价是总是对虚函数进行调用,因此空的 dont_print 确实有很小的代价。对于性能关键区域,这可能是可接受的,也可能是 Not Acceptable 。

关于c++ - 为什么更喜欢模板方法而不是依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8134436/

相关文章:

c++ - WINAPI 事件对象意外行为

c++ - 使用 VS 公共(public)继承进行模板化

c++ - 无法编译在不同类上调用静态函数的代码

c++ - 重载函数不编译

java - 将依赖注入(inject)与 Apache Commons IO 结合使用

c++ - 分离线程的参数问题

c++ - 如何为明星节目添加空间

c# - Unity选择带参数的构造函数

c# - 从外部应用程序读取屏幕上的文本。 API Hook ?

java - 使用 Guice 的逆向工程项目的策略?