1

考虑以下简化的类:

class Book {
   string title;
   Author author;
}

很简单。但是,当添加类似的方法时getBookFromDatabase(int bookId),应该将其作为static 方法放在同一个类中,还是放在单独(即)BookManager类中?

使用示例:

Book b = Book.getBookFromDatabase(42);

对比

Book b = BookManager.getBookFromDatabase(42);

我确实意识到这在某种程度上是一个品味问题,但是遵循 OOP 指南的最佳方法是什么?

4

6 回答 6

3

我更喜欢使用 aRepository来为后备存储中的对象补充水分。以下内容可能是一个很好的起点。

public interface IBookRepository{
    Book Load(int id);
    void Save(Book book);
} 

这样,您可以拥有多个不同的存储库实现,而不必依赖于使用数据库。例如,您可能有一个InMemoryBookRepository可用于测试和一个DatabaseBookRepository用于类似生产环境的环境。

从风格上讲,我也会避免使用静态方法,例如:

BookManager.getBookFromDatabase(42);

它更难测试,并且生成的代码更紧密地耦合在一起,这将使测试和更改变得更加困难。

您可以查看这个StackOverflow 问题,了解在哪里可以了解有关实现存储库的更多信息。 MicrosoftMartin Fowler也更详细地描述了它。

于 2012-12-09T14:45:27.080 回答
2

就个人而言,我喜欢 " Manager" 类的方法。它分离了逻辑,因此 aBook不必知道如何获取自身。此外,BookManager这里可以是单例 - 直到实际需要获取Book.

此外,BookManager可以执行额外的簿记任务(没有双关语),例如缓存,或者可能有一些Book事件需要在全局级别订阅。

于 2012-12-09T14:35:24.003 回答
0

我假设您的 Book 类是域/业务类,因此将从数据库中检索数据的责任放在类本身上,您正在创建数据库和业务层之间的高度耦合,这违反了良好的原则设计。

我会推荐你​​阅读http://en.wikipedia.org/wiki/GRASP_(object-oriented_design )

如果你愿意的话,得到一份

应用 UML 和模式:面向对象分析、设计和迭代开发简介 - Craig Larman 着 ISBN13:978-0131489066

这本书是最受欢迎的软件开发书籍之一,强烈推荐。

于 2012-12-09T15:53:09.323 回答
0

我相信使用单独的类会更好。这可能是 BookManager,但也许有更适合图书馆或书店之类的工作的东西。该对象应包含对数组或 ArrayList 中书籍的引用(我建议使用 ArrayList),如下所示:

public class BookManager {
    ArrayList<Book> books = new ArrayList<Book>();

    public Book getBook(int index) {
        return books.get(index);
    }

    public void addBook(Book book) {
        books.add(book);
    }
}
于 2012-12-09T14:41:22.877 回答
0

这取决于。

如果您的所有Book类的行为都是存储从数据库中检索的字段,那么您可能更简单地添加从数据库获取数据的行为,即getBookFromDatabase(int bookId)在同一个类上,因为所有类都会关注从数据库中检索一本书并将其连贯地呈现给程序的其余部分。

但是,如果您打算让您的类具有其他行为,也许是特定于您的应用程序的某些 Book 业务逻辑,那么将业务逻辑与持久性逻辑分开Book可能更有意义。

这里的指导性启发式应该是单一责任原则,关于它的 stackoverflow还有很多其他问题。

还要记住,在单独但相关的注释中,静态方法是可测试性的死亡

于 2012-12-09T14:42:29.727 回答
0

您的两种方法都使用本质上非 OOP 的静态方法。最好的解决方案是拥有一个BookDatabase对象,并且该对象应授予对其包含的书籍的非静态访问权限。

这将解决静态方法带来的问题。例如,如果您将来有两个或更多 BookDatabases 怎么办?使用静态方法,这会变得混乱。使用数据库对象,您只需拥有更多此类(或子类)的实例来处理不同的数据库。

于 2012-12-09T14:43:54.953 回答