如何包装服务,使其更简单


11

我们依赖于第三方服务,该服务公开了一个巨大的接口,我们只需要像3种方法。此外,界面经常更改...

我决定将接口包装在我们项目的一个类中,只公开我们需要的方法。

但是我不确定如何处理返回值...接口返回类型为的对象Storage。我们内部有一个类型StorageModel,它是a的内部表示形式Storage

您将在映射器中返回什么:StorageStorageModel?我们有一个DataService StorageService,它获得了注入的包装的依赖关系。

目前,我基本上是这样的:

public class StorageService 
{
    private readonly IExternalStorageWrapper externalStorageWrapper;

    public StorageService(IExternalStorageWrapper externalStorageWrapper)
    {
        this.externalStorageWrapper = externalStorageWrapper;
    }

    public StorageModel GetStorage(int storageId)
    {
        return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel();
    }
}

public class ExternalStorageWrapper : IExternalStorageWrapper
{
    public Storage GetStorage(int storageId)
    {
        using(var ext = new ExternalStorage())
        {
            return ext.GetStorage(storageId);
        }
    }
}

你打算说什么:

  • 像上面这样好,包装器返回外部Storage对象,内部StorageService返回内部对象StorageModel
  • 还是您StorageModel已经在包装器中返回了?

2
为什么命名为包装纸?更好地寻找立面,桥梁和适配器模式。据我了解,包装器将提供第三方服务的所有方法-但这不是您想要的。
Tobias Otto


@TobiasOtto的包装并不需要公开所有的包装对象的行为,请参阅本文中“A限制包装”。
guillaume31 '18

Answers:


11

根据我的选择,包装程序应处理与外部库有关的所有事情。这意味着包装器的公共接口不得命名任何外部类型。

将外部类型映射到应用程序的相应类型是包装程序的职责之一。如果这不是一个简单的操作,则可以使用各种可用的工具来分解问题,例如,注入翻译器对象。但是,翻译器仍必须是包装器模块的一部分,并且应用程序的其他任何部分都不能依赖它。

这样,您的应用程序的其余部分不仅完全不受库中的更改的影响,而且还完全不受其他库的替换的影响。


3

我决定将接口包装在我们项目的一个类中,只公开我们需要的方法。

没关系。这也称为Adapter

您选择Adapter模式,因此此处的目的是一个接口(库模型)转换为另一个(域模型)。因此,如果前者的某些内容到达了域模型,则适配器将无法达到其目的

根据前面的参数,适配器应返回StorageModel

最终,你的域“说话”特定的语言,在这里Storage是一个陌生人

但是我不确定如何处理返回值...

这里的关键是要知道包装/修改库的原因是什么

适配器,装饰器,外墙模式可能有相似之处,但有很大不同。他们解决的问题各不相同。

也就是说,您可能也对以下内容感兴趣:


1

您无法通过复制有效地包装库。

您应该包装的是库的用法,这意味着不公开对象(在本例中为Storage)。也不要尝试复制它们。

使用库,但将其包含在内。因此,在您的情况下,假设您使用StorageService存储事物,则应将其包装在存储库中

MyPocoObjectRepo
    MyPocoObject GetObject(string id);

MyPocoObject完全是您的数据和业务逻辑。不能复制存储或DataReader或任何东西


0

答案是,这取决于您是否需要Storage直接从否类中进行访问StorageModel

如果要包装库,则还应包装由它返回的对象,以便将来对库所做的更改进行证明。但是,如果您需要Storage直接使用,则意味着可能需要Storage根据情况返回。可以说是强制Storage使用此处的一种说法,StorageModel因为您可能希望在整个程序中保持一致。

我强烈建议您包装接口和返回的对象(如果您尚未包装的话),尽管如此,这仅在您只StorageModel在整个程序中使用而不是在整个程序中才有意义Storage

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.