首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不调用装饰实例的装潢师-需要替代设计

不调用装饰实例的装潢师-需要替代设计
EN

Software Engineering用户
提问于 2013-06-25 11:17:51
回答 2查看 118关注 0票数 1

假设我有一个用于翻译文本的简单接口(C#中的示例代码):

代码语言:javascript
复制
public interface ITranslationService
{
    string GetTranslation(string key, CultureInfo targetLanguage);
    // some other methods...
}

这个接口的第一个简单实现已经存在,只需为每个方法调用进入数据库。假设启动时正在翻译UI,则每个控件都会有一个数据库调用。

为了改进这一点,我想添加以下行为:

一收到对一种语言的请求,就从这种语言中获取所有的翻译并缓存它们。所有翻译请求都从缓存中处理。

我考虑将这个新行为作为装饰器来实现,因为由装饰者实现的接口的所有其他方法都将简单地委托给修饰的实例。

但是,GetTranslation的实现根本不会使用修饰实例的GetTranslation来获得特定语言的所有翻译。它将对数据库启动自己的查询。

这破坏了装饰器模式,因为装饰实例提供的所有功能都被跳过。如果有其他装饰师参与,这将成为一个真正的问题。

我的理解是装饰应该是附加的。但是,在这种情况下,装饰器将替换修饰实例的行为。

我真的想不出一个很好的解决办法--你会怎么解决?一切都是允许的,甚至是对ITranslationService本身的完全重新设计。

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2013-06-25 12:38:14

保留ITranslationService,但不要直接针对缓存或数据库实现调用,而是发送到一个对象IRepository,该对象使用首选的IProviders列表,该列表提供了对底层持久性机制的访问。

第一个,或者通常是“首选提供者”,是一个CacheProvider。第二个是您的主LocalDatabaseTranslationProvider。可以想象,可能有第三个或更多的提供者。列表中的最后一个提供程序是最不可取的,但它是可靠的后备提供程序。例如,可以采用第三方翻译服务的形式。它将作为像RemotePartnerTranslationProvider这样的对象代理服务来实现。

每个提供程序都将实现一个公共接口,该接口允许策略不同,因此,无论选择哪个提供程序,无论每个提供程序如何提供读和写,存储库都对每个提供程序进行操作,并以相同的方式从每个提供程序接收。存储处负责在必要时提供供应商之间的协调和冲突解决。

在其他问题中,您也可以查看每个提供程序的可观察接口,因为您需要在存储库中的所有/大多数提供程序之间传播/推送状态/信号,例如在清理/关闭时正确关闭或处理它们。

票数 1
EN

Software Engineering用户

发布于 2013-06-25 11:40:02

许多可能选项的可行性取决于ITranslationService接口当前实现的关闭程度。

  • 如果当前实现完全关闭(最后一个类,将不接受修改),那么您唯一的实际选项是。
    • 创建一个独立独立的接口实现
    • 用你现在的“装潢师”方法。如果无法在缓存中找到转换,则可以将其扩展为调用修饰对象的GetTranslation方法。

  • 如果当前实现允许子类,则可以将缓存版本作为派生类提供。
  • 如果当前的实现仍然开放供修改,您可以将GetTranslation实现更改为使用战略模式,其中一种策略总是进入数据库,而另一种策略使用缓存。
票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/202670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档