2013-02-20 34 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. 

    } 
}