我们应该用什么来代替“经理”?良好的 OOP 设计中的类?
我在设计游戏引擎时遇到了麻烦。例如:
当我想到资源时,我想到ResourceManager类来管理我的引擎上的资源。
这个类有几个职责:
- 加载资源。
- 通过标识符映射资源。
- 确保资源仅加载一次。
- 释放未使用的资源(使用智能指针)。
这对我有用,但我在每个 OOP 设计教程中都读过,管理器是具有高耦合和低内聚的模糊类。我理解这一点,我也同意,但我几乎搜索了整个互联网,以找到经理的真正替代方案的明确示例,但我没有找到。
例如,有人解释说,ResourceManager 应该分为更小的类:ResourceFactory、ResourceCollection、ResourceCache、 ResourceFacade...
我知道所有这些设计模式(工厂、集合、外观等),但我实际上不明白如何将它们结合起来创建一个(易于管理)资源管理系统。
我的问题是:是否有一些带有清晰示例的教程或文档?有人可以解释一下这个系统的例子吗?如果您能用 C++ 或其他类似语言编写一个小示例,我将非常感谢。
预先感谢您的帮助!
I'm having trouble designing my game engine. For example:
When I think in Resources, I think in a ResourceManager class to manage resources on my engine.
This class gets several responsibilities:
- Load resources.
- Map resources by an identifier.
- Ensure that resources are loaded only once.
- Free unused resources (using smartpointers).
This works for me, but I have read on every OOP design tutorial that managers are ambiguous classes with high coupling and low cohesion. I understand this, and I agree, but I searched almost the whole Internet to find a clear example of a real alternative to Managers but I didn't found it.
Some people explain, for example that a ResourceManager should be divided into smaller classes: A ResourceFactory, a ResourceCollection, a ResourceCache, a ResourceFacade...
I know all this design patterns (Factory, Collection, Facade, etc.) But I don't actually understand how this can be joined to create a (easy to manage) resource management system.
My question is: Is there some tutorial or document with a clear example? Can someone explain an example of this system? I'll thank you if you can write a small example in C++ or another similar language.
Thanks in advance for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你几乎已经说过了:
(原来的重点)。
这违反了单一责任原则。此外,“Manager”一词暗示着一个管理其他对象的对象,这与对象应该封装数据和行为的面向对象原则相矛盾。这很快就会导致 Feature Envy 代码气味。
将经理分成许多较小的类别是正确的做法。为了使它们易于管理,您可以在它们之上实现Facade。
You almost said it already:
(original emphasis).
This violates the Single Responsibility Principle. Additionally, the word Manager suggest an object that manages other objects, which is at odds with the object-oriented principle that objects should encapsulate both data and behavior. This quickly leads to the Feature Envy code smell.
Dividing the manager into many smaller classes is the correct thing to do. To keep them manageable, you can implement a Facade over them.
也许:
ResourceLoader
ResourceMapper
CachedResourceLoader
/ 这个在尚未加载时使用ResourceLoader
有关“释放未使用的资源”的评论中有额外信息:
首先,让我们明确一下,我们只涉及上述内容中的两个: ResourceMapper 和 CachedResourceLoader。由于 ResourceLoader 实例是从 CachedResource 使用的,因此它不会暴露给其余代码。
请注意,以下内容取决于领域知识,因此我将保持开放/您会知道其中哪些有意义/适用于您拥有的部分。我想说这里有 3 个选项:
ResourceMapper 中的
最后一点:我认为将责任分开并且对此感到强烈是绝对值得的。也就是说,这是我最遵循的 SOLID 原则,我不会记住模式名称,也不会过多关注诸如 Manager 类之类的规则是不好的。
Maybe:
ResourceLoader
ResourceMapper
CachedResourceLoader
/ this one uses theResourceLoader
when it doesn't already have it loadedre extra info in the comment about "Free unused resources":
First, let's clear that we only have 2 of the above involved: ResourceMapper and CachedResourceLoader. As the ResourceLoader instance is used from the CachedResource, it's not exposed to the rest of the code.
Note that the following depends on the domain knowledge, so I'll keep it open / you'll know which of these make sense / applies to the pieces you have. I'd say there are 3 options here:
A final note: I think it's definitely worth it to separate the responsibilities and feel strong about doing so. That said, it's the SOLID principles I follow the most, I don't memorize pattern names and don't pay that much attention to rules like Manager classes are bad.
您不需要对设计模式或特定架构抱有教条。只需做任何有意义的事情并妥善记录。
换句话说,因为较大的类具有多重职责而将一个类分解为较小的类是一个很好的原则,但不是一个法律。你不想不惜任何代价去追随它。看看应用它的优点和缺点。有时,将一个类分解为更小的类可以让您更好地控制职责,但代价是这些类之间的大量沟通。在您的示例中,您也可以实现不同的类来进行资源加载、缓存、映射、保存等。但是,如果每个类都需要与其他类通信才能执行其工作,那么分解就不值得做,因为它耦合度高,这是不好的;将所有内容放在一个类中。
有时我认为设计模式给软件开发世界带来的损害和清晰度一样多! :-)
You don't need to be dogmatic about design patterns or a particular architecture. Just do whatever makes sense and document it well.
In other words, decomposing a class into smaller classes because the larger class has multiple responsabilities is a good principle, but not a law. You don't want to follow it at any cost. Look at the pros and cons of applying it. Sometimes, decomposing a class into smaller classes gives you more control over responsaibilities, but at the expense of a great deal of communication among those classes. In your example, you might as well implement different classes for resource loading, caching, mapping, saving, etc. But if each class needs to talk to the others in order to perform its work, then the decomposition is not worth doing, because it entails high coupling, which is bad; keep it all in a single class.
Sometimes I think that design patterns have brought about as much damage as clarity to the software development world! :-)
我认为您的解决方案不一定有问题。
恕我直言,如果您从面向方面编程的角度思考您所说的内容,
它只是您的资源的一个方面,将由类处理。
尽管如果你从大的角度思考,你的代码库可能会发展成数百行,所以最好分解你的基础设施功能(领域驱动设计模式)。
我认为您的类是一个有凝聚力的类,并且
manager
名称并不总是一个坏兆头,只是它巩固了许多可能不相关的类的控制流,这些类相互协作以完成任务。如果您对缓存和映射的要求很容易发生变化,也许最好分离您的关注点。
尝试编写组织良好的代码时的经验法则是一开始不要太认真,继续前进时请注意代码异味,并在必要时重构或重构为模式。
I don't think something is necessarily wrong with your solution.
IMHO if you think about stuff you've said from Aspect Oriented Programming's point of view,
it's just an aspect on your resources that will be handled by a class.
Although if you think in large, your code base may evolved in hundreds of lines, so it would be better to break down your Infrastructure functions(Domain Driven Design Patterns).
I think your class is a cohesive one and the
manager
name is not always a bad sign except that it consolidates the control flow of many possibly unrelated classes that collaborate with each other to accomplish a task.If your requirements about caching and mapping is prone to change maybe it would be better to Separate your Concerns.
Rule of thumb when trying to write a well organized code is don't take it too serious at first, watch out code smells as you go forward and refactor or refactor to patterns when necessary.
谁说他们应该结合在一起?然后你又回到了起点,不是吗?分解管理器类的全部要点是您最终会得到多个更简单的组件。如果您需要缓存功能,请与缓存对话。如果您需要资源加载功能,请与资源加载器交谈。
Who says they should be joined together? Then you're back where you started, aren't you? The entire point in breaking up manager classes is that you end up with multiple simpler components. If you need the caching functionality, you talk to the cache. If you need the resource loading functionality you talk to the resource loader.