书籍和标签的OO设计

H-H*_*H-H 10 oop

我正在为一个简单的用例进行面向对象设计的基本练习:一本书可以标记许多标签.

我有很多解决方案,我希望你的投入在OOD原则和可维护性方面更好.

选项1

public class Book {
    private String title;
    //... other attributes

    private List<Tag> tags;
}
Run Code Online (Sandbox Code Playgroud)

困扰我的是我们将书籍的核心属性与其他分类或搜索数据混合在一起.我将来可能会要求某些图书无法被标记.将来,当我添加更多的责任时,Book类会变得臃肿:类别,读取它的用户列表,评级......

选项2

public class TaggedBook extends Book {
    private Book book;

    private List<Tag> tags;
}
Run Code Online (Sandbox Code Playgroud)

我认为这与Decorator模式类似,但我认为它不适合这里,因为我没有扩展行为.

选项3

彻底解耦书籍和标签,并使用服务从书籍中检索标签(鉴于每本书都有唯一的标识符)

List<Tag> TagService.getTags(Book book)
Run Code Online (Sandbox Code Playgroud)

但是,我没有发现这个解决方案非常优雅(是吗?),我可能需要发送两个查询:一个用于检索书籍,另一个用于标记.

我打算将最佳选项应用于其他要求:A Book有评级,Book可以分类......

我还计划使用DMS来存储Books和Tags对象.由于它不是关系数据库,因此其架构可能与类设计相对应.

谢谢

Abd*_*man 7

装饰模式的概念很适合你的情况.但我认为战略模式 在你的情况下更有用和有效.如果你不了解战略模式,那么看看这个.它会给你一个关于策略的好主意如果您需要更多建议或有任何疑问,请在评论中提问.谢谢你一切顺利..


bit*_*onk 5

这三个选项都是有效的,也是您班级设计的不错选择.这完全取决于完整的背景/要求.您列出的要求很可能不足以做出"正确"的决定.例如,如果您的应用程序是以书籍为中心而且标签不需要独立于书籍进行演变或编写,则选项3可能会引入不必要的复杂性.如果设计充当围绕您的实际逻辑门面公共API,你仍然可能会去选择1或2,即使在内部都BookTag是完全解耦总根源.可伸缩性,性能,可扩展性......这些都是您需要平衡并且会影响您的设计的所有可能要求.

如果您正在为企业应用程序的类设计寻找一个良好的形式化方法和指南,我建议您研究领域驱动设计.

此外,不要为未来未知的要求设计类.这也将再次增加无用的复杂性(想想:成本).当您需要重构新的要求时,请确保您有足够的单元测试覆盖您的背部.


Voi*_*ain 1

我更喜欢第三种选择,将它们完全分开。

书籍和标签具有多对多关系,通过将它们分开,您可以更轻松地进行诸如“哪些书籍被‘计算机科学’标记”之类的查询。