Java与OO设计

时间:2009-12-22 20:03:15

标签: java oop

我正在研究一个继承的系统,它有一些设计问题,“OO Buzzwords”不赞成,有些我个人不喜欢。

这是漫画书店的股票和销售处理程序。

我有一个Article课程,可以是任何项目(魔术卡片,玩具),以及继承自文章的Publication课程,该文章代表书籍和杂志。 Publication有作者和可选的发行号,而文章没有。

有一个文章编辑器,它是一个用于创建和修改文章的GUI。由于可以加载带有错误的出版物而不添加卷号,因此使用文章的界面是:

Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();

如果需要,允许将a更改为出版物。

我的一个问题是,如果它使用了引用,可以更优雅地处理,或者至少在我看来。我当前的版本使用在静态版本中包装最后两行的模式,但它看起来仍然很难看,因为它看起来太依赖于状态。


第二个问题是Java(以及大多数“企业”语言)缺少多个调度:EntityManager有一个save()方法,为ArticlePublication s重载。如果我说,这会引起一个巨大的问题,例如:

Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();
EntityManager.save(a);

目前通过让ArticleEditor保存更改(这似乎是错误的)来解决这个问题。

我确信必须有一些方法来调整设计以消除这些问题。 (如果需要的话,我不介意整个重写。)

如何调整设计以消除这些问题?

编辑:出版物也有作者,不仅仅是数字。

6 个答案:

答案 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);
     }
}

saveArticle中的Publication方法可以回调ArticleStore接口中的方法,如果添加了新的子类,则不需要更改EntityManager层次结构。

修改已更新以反映评论。

答案 2 :(得分:0)

  1. 有什么问题?对我来说似乎很好。
  2. 你不能用反射模拟Java中的多个调度吗?

答案 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'类,因为它可能被误认为是一篇文章作为出版物的一部分。 我的示例完全按照问题中的描述使用“文章”,作为所有类型项目(包括出版物)的某种主数据模型。