2013-02-20 36 views
1

道歉,如果这已被其他地方回答,我的搜索没有产生相当我正在寻找的答案。面向对象在哪里放孤儿方法

坦白地说,让我们说我建立了一个书店的应用程序。

我有一个处理我所有的数据库事务的类。我也有扩展数据库类,从调用它自己的构造数据库构造一个“书”类,不再需要实例化数据库类第一:

class Book extends Database { 
    __construct($book_id){ 
     parent::__construct(); 
     $this->databaseGet("SELECT * FROM..."); // method in Database class 
     etc... 
    } 
} 

我可以传递的引用ID“图书'类的构造函数,并创建一个包含从数据库中获取的关于该书的信息的对象以及与给定书相关的几种方法。

但我也想列出数据库中的所有书籍。我的问题是,我在哪里放这个方法和其他方法,没有像“书”这样的上下文?

我可以创建一个单一的一个“getStuff”或“书店”,它扩展了数据库类,其中将包含所有这些一次性使用的方法类。但是这需要它随时加载,因为这些孤儿方法会在整个程序中使用。

我可以创造很多的那家一个方法但这需要实例化类的一个对象,以调用该方法的类,似乎有点小题大做。

他们不是一般的事业,他们必须在商业模式的地方。我应该在哪里放置这些孤儿方法?

+1

为什么'Book'延长'Database'? Extension =“是” – MikeB 2013-02-20 23:58:21

+0

True。它将它扩展为赋予数据库的通用CRUD函数。它不需要首先实例化数据库,因为在其他调用它的类中没有函数的情况下,数据库是无用的。 – lewis 2013-02-21 00:00:46

+0

不,书或书是CRUD函数的参数/结果。它们映射到“购买”或“销售”或“废料”或“FindUnderBed”。你不删除一本书,你不再有库存。你通过从数据库中删除它来实现它。书不是一个数据库,它只是松散地连接到一个数据库。 – 2013-02-21 00:18:48

回答

2

如果我理解它,你会问代码应该在哪里与特定类型相关,但不会实现类型本身的行为。没有单一的答案。根据系统的总体设计,它可能是类型的一部分 - Smalltalk类具有“类字段”和“实例字段”,并且没有任何错误 - 或者它可能在任何有意义的地方结束。如果它涉及到类型本身的外部事物 - 也就是说,它不仅仅是一个实例行为的问题,而是一个与外部事物相互作用的问题 - 将它放在外部也许是有意义的。例如,你可能有Book,BookDatabase,BookForm,BookWebService等等。在一些成员很少的类中没有什么坏处,你永远不知道什么时候你想添加更多。

+0

这很有道理。也许我试图让事情结构严密。 – lewis 2013-02-21 11:03:59

2

书是书,书是书的集合。 数据库是你可以用来保存大量书籍的一件事,所以你不必再次输入。

它可能是一个XML文件,Excel电子表格,甚至是一个Web服务。

所以写图书和书籍,然后写类似

BookDatabase扩展数据库与像 书籍GetBooks方法(); 和 void SaveBook(Book argBook); 真正的诀窍在于无论书籍和书籍的存储方式如何,Book和Books都可以正常工作。

还有很多东西需要学习,但首先要做的是重新开始,而不是让数据对象依赖于特定的“数据库”。

+0

我明白你在说什么,我想我过分简化了。 '数据库'可能是'Datastore'或'DataFromSomewhere'。糟糕的词语选择。 :) – lewis 2013-02-21 11:03:25

+0

这是一个我们都陷入困境的陷阱。几十年来,这是一种攻击这种问题的传统方式,我们都倾向于毫不犹豫地陷入困境。当你有时间时,看看DI,嘲笑和服务定位器模式。这是一个包括OO在内的一切的时刻。 – 2013-02-21 12:13:12

+0

谢谢Tony!我会看看那个! – lewis 2013-02-21 14:01:17

0

似乎你的设计严重瑕疵。您必须分开三个问题:

  1. 您的域图层(DM):在这种情况下,图书属于它。
  2. 数据访问层(DAL):处理数据库存储。域层根本不知道这个层。
  3. 服务层(SL):处理用例。用例可能涉及来自域的多个对象,以及调用DAL来保存或检索数据。服务层中的方法执行一个工作单元。

一个简单的例子:

// Model Object 
     class Book { 
      title; 
      author: 
      isbn; 
      constructor(title, author, isbn) {// ...} 
      // other methods ... 
     } 


// DAL class 
class BookDataMapper { 
     // constructors ... 

     save(Book book) {} 
     Book getById(id) { 
      String query = get from book table where book_id = id; 
      execute query; 
      parse the result; 
      Book book = new Book(parsed result); 
      return book; 
     } 
     Book getByTitle(title) {} 
     ... 
     getAll(){} // returns all books 

    } 

//Service class 
class BookService { 

    BookDataMapper bookMapper; 


    buyBook(title) { 
     // check user account 

     // check if book is available 
     Book book = bookMapper.getBytitle(title); 

     if book available 
     charge customer 
     send the book to ship etc. 

    } 
}