2010-02-19 45 views
5

這是我經常遇到的一個設計問題,我希望找到關於該主題的一些常見見解。這裏提供的代碼僅僅是一個例子。OOP設計:如何將DB處理合併到應用程序對象中

在設計階段很容易決定你需要一個對象:

User 
========== 
Unique ID 
Login name 
Password 
Full name 

而且很容易把它轉換成一個數據庫對象:

CREATE TABLE user (
    user_id INT NOT NULL PRIMARY KEY, 
    username VARCHAR(15) NOT NULL UNIQUE, 
    password_hash CHAR(32) NOT NULL, 
    full_name VARCHAR(50) 
); 

我的疑惑開始在PHP的水平。最明顯的轉換:

<?php 
class User{ 
    public $user_id, $username, $full_name; 
} 
?> 

不過,我應該怎麼填寫實際值?

我可以保持類DB無關:

<?php 
class User{ 
    public $user_id, $username, $full_name; 
    public function __construct($user_id, $username, $full_name){ 
     $this->user_id = $user_id; 
     $this->username = $username; 
     $this->full_name = $full_name; 
    } 
} 
?> 

但我需要運行查詢別的地方...

我可以封裝它的類構造函數中:

<?php 
class User{ 
    public $user_id, $username, $full_name; 
    public function __construct($user_id){ 
     $sql = 'SELECT username, full_name FROM user WHERE user_id=?'; 
     $parameters = array($user_id); 
     $res = get_row_from_db($sql, $parameters); 

     $this->user_id = $user_id; 
     $this->username = $res['username']; 
     $this->full_name = $res['username']; 
    } 
} 
?> 

這看起來很優雅,但它阻止我做很多類的東西:

  • 驗證通過論壇帖子的用戶名和密碼($ user_id是還不知道)
  • 打印用戶信息用戶(我買不起100個查詢,以顯示100個用戶)

最有可能的,我需要定義幾個類,但我不知道如何組織它。一個基類和許多子類?獨立課程?具有特定方法的單個類?也許這是一個衆所周知的設計模式,但我被教過程式編程。

我也很感激的一些想法:

  • 處理用戶
  • 在會話中存儲信息的集合,所以DB並不需要在每個頁面請求要查詢

====對於記錄====

我已標記戈登的答覆作爲答案爲它提供有趣的閱讀。無論如何,這是值得指出的是,我已經在這可以總結如下PHP手冊的對象序列化頁面的用戶評論一經發現一個very illustrative code snippet

  • 它使用一個類。
  • 一個實例代表一個特定的用戶。
  • 構造函數提供了用戶詳細信息。
  • 該類提供靜態方法以獲得必需的功能,然後才能創建實例。通過ID或名稱從數據庫中提取用戶。
  • 用戶實例可以序列化爲會話數據。

不是一個面向對象的大師,我發現它非常簡單但乾淨而實用。面向對象的文本有過分簡單的任務的傾向,我的日常工作主要是在小型項目中。

+0

您將如何使用第二種方法創建新用戶?數據庫中不存在新用戶。 – Rune 2010-02-19 13:05:07

+0

你提到的代碼片段看起來像是我對ActiveRecord模式的一個實現。 – Gordon 2010-02-28 11:32:13

回答

7

這取決於你的架構。四種常見數據源的體系結構模式可在Martin FowlerPatterns of Enterprise Application Architecture找到:

  • Table Data Gateway

    充當網關到數據庫表的對象。一個實例處理表中的所有行。

  • Row Data Gateway

    充當網關的單個記錄在數據源中的對象。每行有一個實例。

  • Active Record

    在一個數據庫中的表或視圖包裝了一個行的對象,封裝了數據庫訪問,以及在該數據添加域邏輯。

  • Data Mapper

    映射器的一個層,其目的和同時保持它們彼此獨立,並映射器本身的數據庫之間移動數據。

而且圖案:

2

你有沒有考慮使用對象關係映射庫像DoctrinePropel

+0

不是。我希望提高自己的設計技能,而不是學習第三方庫。 – 2010-02-22 10:36:58

+0

我會懷疑在一個已經存在好的解決方案的領域提高你的設計技能是否是提高**最有效的地方。如果您使用體面的第三方庫,您可以騰出時間在沒有第三方解決方案的地區提高設計技能。 – 2010-02-22 11:13:29

+0

不過,我希望即使沒有框架也能編寫出好的代碼。你知道的一般文化。 – 2010-02-25 11:19:16

相關問題