Java与OO设计

Java与OO设计,java,oop,Java,Oop,我正在研究一个继承的系统,它有一些“OO流行语”不喜欢的设计问题,有些我个人不喜欢 这是一个漫画书店的库存和销售处理程序 我有一个文章类,可以是任何物品(魔法卡、玩具),还有一个出版物类,继承自文章,代表书籍和杂志。出版物有作者和发行号,而文章没有 有一个文章编辑器,它是一个创建和修改文章的GUI。由于可以加载带有错误的出版物,而不添加卷号,因此处理文章的界面为: Article a = EntityManager.loadArticle(articleId); ArticleEditor ed

我正在研究一个继承的系统,它有一些“OO流行语”不喜欢的设计问题,有些我个人不喜欢

这是一个漫画书店的库存和销售处理程序

我有一个
文章
类,可以是任何物品(魔法卡、玩具),还有一个
出版物
类,继承自文章,代表书籍和杂志。
出版物
有作者和发行号,而文章没有

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

Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();
如果需要,允许将文件更改为出版物

我最恼火的一点是,如果它使用了引用,或者至少在我看来是这样,那么它的处理会更加优雅。我当前的版本在静态版本中使用了包装最后2行的模式,但它仍然看起来很难看,因为它看起来太依赖于状态


第二个问题是Java(以及大多数“企业”语言)缺少多分派:EntityManager有一个
save()
方法,对
文章和
出版物都重载。如果我说,这会引起一个巨大的问题,例如:

Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();
EntityManager.save(a);
目前,通过让ArticleEditor保存更改(这似乎是错误的),可以“解决”这个问题

我相信一定有办法调整设计以消除这些问题。(如果需要的话,我不介意整个重写过程。)

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

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

  • 有什么问题吗?我觉得很好
  • 您不能使用反射在Java中模拟多个分派吗
  • 有什么问题吗?我觉得很好
  • 您不能使用反射在Java中模拟多个分派吗

  • 我不知道第一个问题。对于第二种情况,确实有时需要多次分派,但在您的情况下可能不需要,如果(发布的文章实例)保存((发布)文章)
    ,则简单的
    。你只有几门课,不要设计过度。

    我不知道第一个问题。对于第二种情况,确实有时需要多次分派,但在您的情况下可能不需要,如果(发布的文章实例)保存((发布)文章)
    ,则简单的
    。你只有几个类,不要试图过度设计。

    我不知道你想从多大程度上重构这个系统,但我怀疑你为什么会有一个单独的发布类,仅仅因为它是一篇有发布号的文章。特别是当你偶尔提到需要将文章更改为出版物时。您可以允许文章具有“publicationnumber”属性,如果文章不是出版物,则该属性可以为null。这消除了将文章更改为发布的需要(只需将属性设置为非null值),也消除了EntityManager的问题


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

    我不知道你有多想彻底重构这个系统,但我怀疑为什么你会有一个单独的发布类,仅仅因为它是一篇有发布号的文章。特别是当你偶尔提到需要将文章更改为出版物时。您可以允许文章具有“publicationnumber”属性,如果文章不是出版物,则该属性可以为null。这消除了将文章更改为发布的需要(只需将属性设置为非null值),也消除了EntityManager的问题


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

    我猜你的意思是
    a=editor.getValue()在您的示例中

    第1期不是真正的问题,除非你说你的文章和出版物是不可变的类?编辑器是在文章实例上创建的,如果它与该对象引用一起使用,其内容将发生更改(在UI中进行确认/回滚描述后,可能会对其进行更改)

    根据您的描述,我假设文章充当出版物的“模板”,并且在UI中创建出版物的操作与编辑文章或出版物的操作是分开的。您可以按如下方式对新出版物的创建进行编码:

    Publication p = EntityManager.newPublication(articleId);
    ArticleEditor editor = new ArticleEditor(p);
    
    问题2可以通过在文章中实现save方法并在发布中重载来解决:

    interface ArticleStore {
    }
    
    class Article {
        void save(ArticleStore store);
    }
    
    class EntityManager implements ArticleStore {
         void save(Article a) {
             a.save(this);
         }
    }
    
    Article
    Publication
    中的
    save
    方法可以调用
    ArticleStore
    界面中的方法,如果在层次结构中添加了新的子类,则不需要在EntityManager中进行更改


    编辑更新以反映评论。

    我猜你的意思是
    a=editor.getValue()在您的示例中

    第1期不是真正的问题,除非你说你的文章和出版物是不可变的类?编辑器是在文章实例上创建的,如果它与该对象引用一起使用,其内容将发生更改(在UI中进行确认/回滚描述后,可能会对其进行更改)

    根据您的描述,我假设文章充当出版物的“模板”,并且在UI中创建出版物的操作与编辑文章或出版物的操作是分开的。您可以按如下方式对新出版物的创建进行编码:

    Publication p = EntityManager.newPublication(articleId);
    ArticleEditor editor = new ArticleEditor(p);
    
    问题2可以通过在文章中实现save方法并在发布中重载来解决:

    interface ArticleStore {
    }
    
    class Article {
        void save(ArticleStore store);
    }
    
    class EntityManager implements ArticleStore {
         void save(Article a) {
             a.save(this);
         }
    }
    
    Article
    Publication
    中的
    save
    方法可以调用
    ArticleStore
    界面中的方法,如果在层次结构中添加了新的子类,则不需要在EntityManager中进行更改

    编辑