如何通过设计模式改进多态性

发布于 2024-09-30 06:16:24 字数 1086 浏览 2 评论 0原文

我正在尝试设计一个允许处理多种类型文件的系统。这个想法是,有一个应用程序来处理磁盘上文件的实际操作,而开发人员可以编写自定义库,这些库将能够在加载后对文件执行任何他们想要的操作。

我当前的结构如下所示:

原始图像 当前类图

应用程序发布一个 IClient 接口,自定义编写的库可以自由实现该接口。 Client1Client3 都有不同的实现,并以不同的方式响应每种类型的文件。

File 上的 Populate 方法在派生类中被重写,以调用 IClient 接口上正确的 PopulateFrom 方法,传入调用文件。

因此,实现 IClient 的类上的 PopulateFrom 方法会传递一个特定类型的文件,以便它必须访问底层数据(CSVDataReader 或本例中的 XDocument)解析为它想要的任何特定于域的对象。

对于添加到系统中的每种新文件类型使用此设计,我必须向 IClient 添加一个新方法,这并不理想。为了保持与没有接受新文件类型的方法的客户端类的兼容性,我必须创建一个专门支持该类型的新接口,并让新客户端实现:

原始图片 具有新文件类型的类图

这一切都有效,但我想知道是否有更好的方法来支持多种文件类型,而无需每次都必须添加新界面,可能使用设计模式吗?

I'm attempting to design a system that will allow the processing of multiple types of file. The idea being that there's a single application to handle the actual manipulation of the files on disk, while developers can write custom libraries that will be able to do whatever they want with the files once loaded.

I current have a structure that looks like this:

Original Image
current class diagram

Where the application publishes an IClient interface that the custom written libraries are free to implement. Client1 to Client3 would each have a different implementation and respond to each type of file in a different way.

The Populate method on File is overriden in the derived classes to call the correct PopulateFrom method on the IClient interface, passing in the calling file.

Therefore the PopulateFrom method on the class implementing IClient is passed a file of a specific type so that it has to access the underlying data (CSVDataReader or XDocument in this example) to parse into whatever domain-specific objects it wants.

Using this design for every new type of file I add to the system I would have to add a new method to IClient which isn't ideal. To preserve compatibility with the client classes that don't have the method accepting the new file type I'm going to have to create a new interface that specifically supports that type and have the new client implement that:

Original Image
class diagram with new file type

That all works, but I was wondering whether there's a better way of supporting the multiple file types without having to add a new interface every time, possibly using a design pattern?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

素罗衫 2024-10-07 06:16:24

这里有一个选项:您的 PopulateFrom 方法不应采用特定的文件类型,而应采用 FileStreamMemoryStream,毕竟是一个文件只是一个字节流,正是这些字节的组织使每种文件类型都是唯一的。

此外,您可能想要实现与此类似的方法:

bool CanProcess(FileStream myFile)

这样您可以以通用方式查询每个提供程序,它会告诉您它是否可以处理该特定文件。通过这种方式,您可以实现更多的文件类型和更多的提供程序,而不必扩展您的接口或扰乱现有的提供程序。

查看提供者模式看看是否有帮助。

Here is an option: your PopulateFrom method should not take a specific file type, instead it should take a FileStream or MemoryStream, after all a file is simply a stream of bytes, it is the organisation of those bytes that makes each file type unique.

Additionally, you may want to implement a method similar to this:

bool CanProcess(FileStream myFile)

that way you can query each provider in a generic way and it will tell you if it can process that particular file. Doing it this way will allow you to implement more file types and more providers without having to extend your interface or mess with the existing providers.

Check out the Provider pattern to see if it helps.

兲鉂ぱ嘚淚 2024-10-07 06:16:24

您的设计违反了称为依赖倒置的设计原则,因为客户端依赖于具体类而不是抽象类。

您应该重新考虑以使用抽象类型(Application::File)的方式来实现您的客户端。如果绝对没有办法做到这一点,那么您应该重新设计类层次结构。

想一想。如果很少使用抽象,那么它可能毫无用处。罗伯特·马丁将此称为稳定抽象原则。

Your design violates the design principle known as Dependency inversion, because clients depend on concrete classes instead of abstract ones.

You should reconsider implementing your clients in a way they work with the abstract type (Application::File). If there's absolutely no way to do that, then you should redesign the class hierarchy.

Think about it. If an abstraction is seldom used then it is probably useless. Robert Martin terms this as the Stable abstractions principle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文