考虑以下简化类:
class Book {
string title;
Author author;
}
足够简单。但是,在添加getBookFromDatabase(int bookId)
等方法时,应将其作为static
方法放在同一类中,或而不是分开(即)BookManager
- 类?
用法示例:
Book b = Book.getBookFromDatabase(42);
VS
Book b = BookManager.getBookFromDatabase(42);
我确实意识到这在某种程度上是一种品味问题,但是在OOP指导下遵循的是什么?
答案 0 :(得分:3)
我更喜欢使用Repository
来补充后备存储中的对象。以下内容可能是一个很好的起点。
public interface IBookRepository{
Book Load(int id);
void Save(Book book);
}
这样,您可以拥有多个不同的存储库实现,而不必与使用数据库相关联。例如,您可以使用InMemoryBookRepository
进行测试,使用DatabaseBookRepository
进行生产环境。
在风格上,我也会避免使用静态方法,如:
BookManager.getBookFromDatabase(42);
测试更难,结果代码更紧密地耦合在一起,这将使测试和更改变得更加困难。
您可以查看此StackOverflow question,了解有关实施存储库的更多信息。 Microsoft和Martin Fowler也更详细地描述了它。
答案 1 :(得分:2)
就个人而言,我喜欢“Manager
”类方法。它将逻辑分开,因此Book
不必知道如何获取自己。此外,BookManager
可以是单身人士 - 在实际需要获取Book
之前不会实例化。
此外,BookManager
可以执行额外的簿记任务(无双关语),例如缓存,或者可能有一些Book
事件要订阅全球层面。
答案 2 :(得分:0)
我相信使用单独的课更好。这可能是BookManager,但也许有更适合像Library或BookShop这样的工作。该对象应该保存对数组或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);
}
}
答案 3 :(得分:0)
这取决于。
如果您的所有Book
类'行为都存储在从数据库中检索的字段中,那么您可能更容易添加从数据库获取数据的行为,即getBookFromDatabase(int bookId)
同一个班级,因为所有课程都与从数据库中检索一本书并将其紧密地呈现给该计划的其他部分有关。
但是,如果您打算让Book
类具有其他行为,可能是某些特定于您的应用程序的Book业务逻辑,那么将业务逻辑保留可能更有意义与持久性逻辑分开。
这里的指导启发式应该是Single Responsibility Principle,关于它有plenty of other questions on stackoverflow。
单独但相关的说明答案 4 :(得分:0)
您的两种方法都使用本质上非OOP的静态方法。最好的解决方案是拥有一个BookDatabase
对象,该对象应授予对其包含的书籍的非静态访问权。
这将解决静态方法带来的问题。例如,如果您将来有两个或更多BookDatabase怎么办?使用静态方法,这会变得混乱。使用Database对象,您只需要有更多此类(或子类)的实例来处理不同的数据库。
答案 5 :(得分:0)
我假设您的Book类是一个域/ Business类,因此将数据从类数据库本身检索到它的责任,您在数据库和业务层之间创建了高度耦合,这与良好设计原则。
我建议您阅读http://en.wikipedia.org/wiki/GRASP_(object-oriented_design)
如果你愿意,可以获得
的副本应用UML和模式:面向对象的分析和设计及迭代开发简介 - 作者:Craig Larman ISBN13:978-0131489066
这本书是最受欢迎的软件开发书之一,强烈推荐。