为什么更喜欢模板方法而不是依赖注入?

2023-12-26

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

使用模板方法,您可以使用为所需操作或计算提供替代方案的策略来“模板化”类。因此,您不需要从多种替代方案中选择一种策略并将该策略编码到类中,而是允许类的用户指定他们想要使用的替代方案。

这一切对我来说听起来都很合理。但我在概念上遇到了一些障碍。

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

如果你要定义一个摘要IPolicy对于这些策略对象,为什么不直接使用依赖注入并传入IPolicy关于施工?

谁能解释一下为什么您更喜欢模板方法而不是依赖注入?


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

带模板

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 确实有很小的代价。对于性能关键区域来说,这可能是可接受的,也可能是不可接受的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么更喜欢模板方法而不是依赖注入? 的相关文章

随机推荐

  • 从 tpl Sencha 传递参数

    我的json如下 status TRUE message Words data name paint author snooky word id 1 category Business definitions rating Green de
  • 在 android studio 中编译项目时出现重复条目​​:com/android/volley/AuthFailureError.class

    我正在使用外部库 payu Money sdk 和 linkedin sdk 两者都使用 volley 库 在编译项目时会给出 AuthFailureError class 的重复条目 错误 任务 app packageAllDebugCl
  • AndroidHttpClient 和 DefaultHttpClient

    这两者之间有很大区别吗 最好使用哪一个 基于Android源码 https github com CyanogenMod android frameworks base blob gingerbread core java android
  • const 后出现意外的令牌

    当我尝试指定一个常量时 我 在 React 中遇到了意外的令牌错误 但我似乎无法弄清楚原因 我的代码非常简单 并且我遵循了react bootstrap示例here https react bootstrap github io compo
  • 如何在使用 fstream 打开文件时截断文件

    我知道可以用以下命令截断文件 std fstream fs mypath std fstream out std fstream trunc 但我需要读取文件 截断它 然后使用相同的文件句柄写入新内容 因此整个操作是原子的 任何人 我不认为
  • Rails 用户:您使用什么异常通知软件?

    我见过 Ryan Bates 谈论过异常记录器和异常通知 还有其他好的可以考虑吗 您喜欢和不喜欢这些内容的哪些方面 另外 如果您捕获这些异常通知程序 它们是否会记录异常 Thanks 我强烈推荐使用Hoptoad http hoptoada
  • wget 拒绝仍然下载文件

    我只想要文件夹结构 但我不知道如何使用 wget 相反 我正在使用这个 wget R pdf css gif txt png np rhttp example com http example com 它应该拒绝 R 之后的所有文件 但在我
  • 为 kendo ui 网格列定义自定义模板

    我有一个 kendo ui 网格 我想绑定图像 这是我的代码 model List
  • APScheduler(高级 Python 调度程序)导入错误:没有名为调度程序的模块

    我遇到以下导入错误 导入错误 没有名为调度程序的模块 当我运行以下 python 脚本时 Demonstrates how to use the blocking scheduler to schedule a job that execu
  • 如何在React Native中离线捆绑iOS?

    任何人都可以解释一下如何从 反应本机 代码生成 iOS 应用程序的离线包吗 我已经尝试过了如何为react native生成 ipa文件 https stackoverflow com questions 41970435 how to g
  • 如何递归连接字符串元素列表

    我正在查看准备考试的示例 坦率地说 我不太擅长递归或列表 尤其是列表 给定一个节点类 它将保存字符串 不是通用的 编写一个名为 concat 的递归 java 函数 该函数采用表示链表头的节点 并返回表示链表中所有元素的串联的字符串 如果链
  • 对列表进行子集化 - plyr 方式?

    我经常拥有按一个或多个变量分组的数据 每组内有多个注册 从数据框中 我希望根据各种标准选择组 我通常使用 split sapply rbind 方法 其中使用逻辑向量从列表中提取元素 这是一个小例子 我从一个包含一个分组变量 组 的数据框开
  • 如何在 Jenkins (VS2012) 中运行发布/点击一次构建步骤

    我们有一个简单的 C 解决方案 VS 2012 它有一个发布步骤 单击一次向导 使用 ftp 我已经设置了一个 jenkins 构建项目来在 SVN 触发器上构建它 通过 MSBuild 我无法让它构建 通过 MSBuild 发布 单击一次
  • WPF 嵌套 Scrollviewers - 将控制权交还给父级 scollviewer

    这就是我的控制树的样子
  • Android P 预览上的 toast View 的 IllegalStateException

    在尝试发布我的应用程序进行生产时 预发布报告通知我 Pixel 2 Android P Preview 设备上出现错误 该错误与我的自定义 toast 消息有关 该消息表示视图 已添加到窗口管理器 java lang IllegalStat
  • 不用sudo重启nginx?

    所以我希望能够在不输入任何密码的情况下进行 cap deploy 我已经设置了所有私钥 这样我就可以很好地访问远程服务器 并且现在使用 svn over ssh 所以那里没有密码 我还有最后一个问题 我需要能够重新启动 nginx 现在我有
  • 导入 javax.validation.constraints.NotEmpty;不工作[重复]

    这个问题在这里已经有答案了 我目前有一个 java spring boot 应用程序 我将版本 在代码中 从 2 1 4 更改为 2 3 0 但结果我遇到了错误error package javax validation constrain
  • android服务导出属性?

    我对android平台还很陌生 我想导出我的服务以供公众使用 我在开发人员文档中找到了一些内容 android exported其他应用程序的组件是否可以调用该服务或与其交互 如果可以 则为 true 如果不能 则为 false 当值为 f
  • 为闪亮仪表板中的滑块添加不同的静态颜色

    我是闪亮的新手 我想为滑块提供静态颜色 无论闪亮仪表板中选择的范围如何 我想要滑块有不同的颜色 如下所示 例如 0 到 40 红色 40 到 60 蓝色 60 到 100 绿色 请帮我解决这个问题 我的代码 library shiny li
  • 为什么更喜欢模板方法而不是依赖注入?

    我一直在阅读 Gamma 等人写的 设计模式 我有一个关于模板方法与依赖注入相比的问题 使用模板方法 您可以使用为所需操作或计算提供替代方案的策略来 模板化 类 因此 您不需要从多种替代方案中选择一种策略并将该策略编码到类中 而是允许类的用