我正在研究一个继承的系统,它有一些设计问题,“OO Buzzwords”不赞成,有些我个人不喜欢。
这是漫画书店的股票和销售处理程序。
我有一个Article
课程,可以是任何项目(魔术卡片,玩具),以及继承自文章的Publication
课程,该文章代表书籍和杂志。 Publication
有作者和可选的发行号,而文章没有。
有一个文章编辑器,它是一个用于创建和修改文章的GUI。由于可以加载带有错误的出版物而不添加卷号,因此使用文章的界面是:
Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();
如果需要,允许将a更改为出版物。
我的一个问题是,如果它使用了引用,可以更优雅地处理,或者至少在我看来。我当前的版本使用在静态版本中包装最后两行的模式,但它看起来仍然很难看,因为它看起来太依赖于状态。
第二个问题是Java(以及大多数“企业”语言)缺少多个调度:EntityManager有一个save()
方法,为Article
和Publication
s重载。如果我说,这会引起一个巨大的问题,例如:
Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();
EntityManager.save(a);
目前通过让ArticleEditor保存更改(这似乎是错误的)来解决这个问题。
我确信必须有一些方法来调整设计以消除这些问题。 (如果需要的话,我不介意整个重写。)
如何调整设计以消除这些问题?
编辑:出版物也有作者,不仅仅是数字。
答案 0 :(得分:2)
我不知道你想要重构这个系统有多么根本,但是我怀疑为什么你会有一个单独的出版课,因为它是一个有出版号的文章。特别是当您提到有时需要将文章更改为出版物时。您可以允许Article具有“发布编号”属性,如果该文章不是发布,则该属性可以为null。这样就不需要将文章更改为发布(只需将属性设置为非空值),这也会使您的EntityManager问题消失。
当然,出版单独的出版课可能还有其他原因,我只是按照我在这里看到的内容。
答案 1 :(得分:1)
我猜你的例子中的意思是a = editor.getValue();
?
问题1不是一个真正的问题,除非你说你的文章和出版物是不可改变的类?编辑器是在Article实例上创建的,如果它与该对象一起使用,则其内容将发生变化(在UI中进行确认/回滚决策后可以更改它。)
根据您的描述,我假设文章充当发布的“模板”,并且在您的UI中,创建出版物的操作与编辑文章或出版物是分开的。您可以按如下方式编写新出版物的创建代码:
Publication p = EntityManager.newPublication(articleId);
ArticleEditor editor = new ArticleEditor(p);
问题2可以通过在Article中实现save方法并在Publication:
中重载来解决interface ArticleStore {
}
class Article {
void save(ArticleStore store);
}
class EntityManager implements ArticleStore {
void save(Article a) {
a.save(this);
}
}
save
和Article
中的Publication
方法可以回调ArticleStore
接口中的方法,如果添加了新的子类,则不需要更改EntityManager层次结构。
修改已更新以反映评论。
答案 2 :(得分:0)
答案 3 :(得分:0)
我不是第一个问题。对于第二个,有时候需要多次调度,但是在你的情况下可能不是这样,简单的if(article instanceof Publication) save((Publication)article)
就好了。你只有几个课程,不要试图过度设计。
答案 4 :(得分:0)
如果你真的想要第二个问题的OO设计,你可以查看访问者模式,虽然这可能是这个小问题的主要过度杀戮,并且使用instanceof将更容易完成这个技巧。 / p>
答案 5 :(得分:0)
当我听到或看到继承的麻烦时,我会考虑使用构图。在您的情况下,替代设计可能是
+-------------+ +---------+
| Publication |--- has-a ---| Article |
+-------------+ +---------+
因此,Publication类将具有类似Article articleReference
的字段以及建模出版物所需的所有字段。保存文章不会干扰出版物,保存出版物将保存出版物和相关文章。
发布编辑器可以扩展文章编辑器并添加所需的发布GUI字段。
缺点是加载包含它的发布数据的文章需要更多的代码行。
修改强>
我建议你重命名'Article'类,因为它可能被误认为是一篇文章作为出版物的一部分。 我的示例完全按照问题中的描述使用“文章”,作为所有类型项目(包括出版物)的某种主数据模型。