2009-12-22 75 views
0

我正在研究一个遗留系统,它有一些“OO Buzzwords”皱眉和一些我个人不喜欢的设计问题。Java与OO设计

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

我有一个Article类,它可以是任何物品(魔术卡,玩具),以及代表书籍和杂志的继承自文章的Publication类。 A Publication有作者和可选的问题编号,而文章没有。

有一个文章编辑器,它是一个GUI来创建和修改文章。既然有装载有错误发布,而不是添加卷数的可能性,该接口与文章的工作是:

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

允许被改变成一个出版物,如有需要。

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


第二个问题带有Java的(也是最“企业”语言)缺乏多分派:EntityManager的有save()方法,重载两个Article S和Publication秒。这会导致如果我说一个巨大的问题,例如:

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

这是目前“解决”由具有ArticleEditor保存更改(这似乎是错误的)。

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

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

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

+5

问题是? – Bozho 2009-12-22 20:05:51

+1

“问题”中没有单个问号。 – mk12 2009-12-22 20:10:17

+1

看到http://bikeshed.com/ – 2009-12-22 20:22:44

回答

0
  1. 什么问题?对我来说似乎很好。
  2. 难道你不能在Java中使用反射来模拟多个派遣吗?
+0

1:看起来很丑陋;我想知道是否有更好的方法。 2:'public boolean save(Article a){if(a instanceof Publication){return save((Publication)a); }/*保存正常的文章* /}'?当然,它可以做到。但是添加Article的另一个子类将意味着修改'save'。 – Tordek 2009-12-22 20:32:37

0

我不是第一个问题。对于第二种情况,有时候确实需要多次调度,但可能不是这种情况,简单的if(article instanceof Publication) save((Publication)article)就好了。你只有几个班,不要试图过度设计。

2

我不知道你想如何从根本上重构这个系统,但我怀疑你为什么会拥有一个单独的出版物类只是因为它是具有出版物号的文章。特别是当你提到有时需要将文章改为出版物。如果文章不是出版物,您可以允许文章具有“出版物编号”属性,该属性可以为null。这就消除了文章变成出版物的需要(只需将该属性设置为非空值),并使EntityManager的问题也消失了。

当然,有一个单独的出版类可能还有其他原因,我只是继续我在这里看到的。

+0

出版物可以是一本书,它有作者,但不是数字(我设置为'null')。我应该澄清一点。 – Tordek 2009-12-22 21:46:57

1

我想你的意思是a = editor.getValue();在你的例子中?

问题1不是一个真正的问题,除非你说你的文章和出版物是不可变的类吗?编辑器是在一个Article实例上创建的,如果它与该对象引用一起工作,它的内容将会改变(在UI中的确认/回滚决定之后可能改变它)。

从您的描述中,我认为文章充当“模板“用于发布,并且在您的UI中,创建发布的操作与编辑文章或发布是分开的。你可以编写新出版的创建是如下:

Publication p = EntityManager.newPublication(articleId); 
ArticleEditor editor = new ArticleEditor(p); 

问题2可以通过实现保存方法在文章和出版物超载得到解决:

interface ArticleStore { 
} 

class Article { 
    void save(ArticleStore store); 
} 

class EntityManager implements ArticleStore { 
    void save(Article a) { 
     a.save(this); 
    } 
} 

save方法ArticlePublication可以调用ArticleStore接口中的方法,如果将新子类添加到层次结构中,则不需要在EntityManager中进行更改。

编辑已更新以反映评论。

+0

为什么你会想把文章变成出版物? – Peter 2009-12-23 07:09:01

0

如果你真的想为你的第二个问题设计一个面向对象的设计,你可以查看访问者模式,虽然这可能是一个重大的杀手这样一个小问题,使用instanceof将更容易完成这个把戏。

0

当我听到或看到继承的麻烦时,我会考虑使用构图。在你的情况下,替代的设计可以

+-------------+    +---------+ 
| Publication |--- has-a ---| Article | 
+-------------+    +---------+ 

因此,出版类将有一个像Article articleReference场和发布建模所需的所有领域。保存文章不会干扰出版物,保存出版物将保存出版物和相关文章。

发布编辑器可以扩展文章编辑器并添加所需的发布GUI字段。

缺点是加载包含其发布数据的文章需要多行代码。

编辑

我建议你重命名“文章”类,因为它可以被误认为是写文章的刊物的一部分。 我的示例完全按照问题中的描述使用'文章',作为某种类型的主数据模型,包括出版物。

+0

从描述中,我假设'文章'用于此处的项目,而不是用于杂志中的一段文字。 – rsp 2009-12-23 09:44:48

+0

很高兴能得到downvoter的评论... – 2009-12-23 19:44:58