2014-05-08 16 views
10

Khi tôi hỏi một câu hỏi về quy ước đặt tên số ít/số nhiều ngày hôm qua, tôi đã gặp phải khái niệm về Mô hình miền. Như tôi đã hiểu cho đến nay, Mô hình miền chỉ đơn giản là một đối tượng đại diện cho một thực thể trong ứng dụng của tôi.Mô hình miền PHP, DAO và cách triển khai

Để sử dụng một ví dụ rất đơn giản, một cái gì đó như thế này:

class User { 

    private $name; 

    public setName() {} 
    public getName() {} 

} 

Bây giờ, câu hỏi nói đến cái tâm, làm thế nào để cư này "Domain Model", hoặc từ một số nguồn đầu vào, từ một cơ sở dữ liệu hoặc nguồn dữ liệu?

Khi đọc về Mô hình miền, tôi đã có ấn tượng rằng sẽ không có gì khác hơn là biểu diễn khái niệm Miền được đề cập bên trong. Vì vậy, bây giờ tôi cũng sẽ cần một lớp (DAO?) Chịu trách nhiệm tương tác với nguồn dữ liệu, trong trường hợp này là một bảng cơ sở dữ liệu có tên là "Người dùng". Lớp DAO của tôi sẽ xử lý chèn, cập nhật, xóa và tìm nạp nhiều lần.

tôi đã đưa ra phương pháp này để Populating một tài khoản Domain Model từ đầu vào, trong trường hợp bài này dữ liệu, và sau đó lưu các bản ghi cơ sở dữ liệu, với một lớp UserDAO:

/** 
* Populating Domain Model from input, and saving to database 
*/ 

/** Instantiate User Domain Model, and populate it from input */ 
$user = new User(); 
$user->setName($_POST['name']); 

/** Creating a new database record from User Domain Model */ 
$userdao = new UserDAO($pdo); 
$userdao->insert($user); 

Và đây là cách Tôi đã dự đoán tương tác với cơ sở dữ liệu khi tôi cần tìm nạp dữ liệu, trong trường hợp này nhiều hồ sơ người dùng:

/** 
* Fetching data from database to populate User Domain Models in an array 
*/ 

/** Instantiate new UserDAO object to interact with User table */ 
$users = new UserDAO($pdo); 
$users->findAll(); 

$user_collection = []; 

/** Loop UserDAO object set to populate user collection array */ 
foreach ($users as $user) { 

    /** Create new User domain object from row, and add to collection array */ 
    $user = new User($user); 
    $user_collection[$user->name()] = $user; 

} 

Có vẻ như lợi ích thực sự duy nhất ở đây là tổ chức.

Lần lặp hiện tại của tôi về cơ bản có lớp Người dùng đảm nhận tất cả trách nhiệm của lớp UserDAO ở trên và trả về mảng dữ liệu trực tiếp từ cơ sở dữ liệu mà tôi sử dụng trong "Bộ điều khiển"/"Trình bày" của tôi thông qua các lượt xem (thụ động) của tôi.

Những gì tôi đang tự hỏi là:

  1. Tôi có đi đúng hướng?

  2. Xác thực đầu vào ở đâu? Tôi cho rằng nó phải nằm trong Mô hình miền, nếu tôi đúng trong các giả định của tôi cho đến nay?

  3. Lợi ích của việc sử dụng kỹ thuật này, ngoài việc giúp tổ chức các khái niệm cơ bản mà ứng dụng sẽ dựa vào và hoạt động là gì? Tại sao tôi cần thêm lớp này thay vì hoạt động trực tiếp trên kết quả mảng từ DB?

+0

Tôi gọi các lớp DAO của tôi là 'Trình xử lý' tức là 'User_handler'. Các trình xử lý này điền các mô hình miền và chấp nhận các bộ dữ liệu để chèn hoặc cập nhật. Việc xác thực đầu vào đang được thực hiện trong bộ điều khiển của tôi. – Timmetje

+0

* strong * related: http://stackoverflow.com/questions/5863870/how-should-a-model-be-structured-in-mvc/5864000#5864000 – ircmaxell

Trả lời

24

Điều quan trọng ở đây là xem lớp nào cần có trách nhiệm và cụ thể là cần có trách nhiệm nào để làm cho chức năng miền của bạn.

tài miền Object

nên có trách nhiệm nói cho bạn về trạng thái của nó đối với các quy tắc kinh doanh hữu ích của ứng dụng của bạn (isAdmin(), isBanned(), isSuspended(), getWarnLevel()) với. Hãy nghĩ về đối tượng này như một xô API. Bạn muốn biết điều gì về nó? Thông tin hữu ích nào có thể cho biết? Xây dựng một API trả lời các câu hỏi đó. Hãy cẩn thận không để cho Người dùng cho bạn biết quá nhiều về các đối tượng KHÁC trong hệ thống. Đó không phải là trách nhiệm của nó.

Cares về:

  • Telling bạn về bản thân
  • Quản lý nhà nước riêng của mình

Không quan tâm đến

  • Cho dù nó được tồn
  • Làm thế nào nó làm
  • Bất kỳ đối tượng khác (trừ khi đó là một gốc tổng hợp)
  • Lots of stuff khác

tài Repository

Một lớp học có trách nhiệm cho phép bạn lấy lại và duy trì hoàn toàn được hình thành, hiện có Users. Có lẽ chúng chỉ tồn tại trong bộ nhớ trong yêu cầu hiện tại. Có thể chúng vẫn tồn tại trong bộ nhớ cache. Có thể họ vẫn tồn tại trong MySQL. Nó không quan trọng. Tất cả điều này làm là cho phép bạn để có được người sử dụng, và tồn tại chúng. Đó là trách nhiệm của nó. Nó có thể, nhưng không phải, biết về cơ chế bền bỉ. Chỉ cần biết cách sử dụng cơ chế kiên trì.

(findById($id), findByEmail($email), findBanned(), findByCriteria($Criteria) - ứng cử viên tốt cho chiến lược hoặc mẫu đặc điểm kỹ thuật, save($User), delete($User)). Một lần nữa, chìa khóa ở đây là xây dựng một API đáp ứng các quy tắc kinh doanh của miền. Bạn có cần tìm người dùng theo địa chỉ email không? Sau đó, làm cho rằng một điểm truy cập rõ ràng trong kho lưu trữ. Nếu bạn không có nhu cầu, thì đừng. Bạn cần tìm số Users như thế nào? Trả lời rằng với một API.

Cares về

  • Cho bạn truy cập vào đối tượng người dùng hiện tại dựa trên bất kỳ tiêu chí tùy ý
  • Gọi cơ chế bền bỉ mà bạn đã cung cấp nó

Không quan tâm

  • Làm thế nào chính xác User đối tượng được tiếp tục tồn
  • Làm User đối tượng
  • Lots of stuff khác

Factory tài

UserRepositories là để xử lý User đối tượng hiện có, nhưng làm thế nào để bạn tạo chúng trong nơi đầu tiên? Với các nhà máy. Đây có thể là các nhà máy đơn giản, chỉ cần tạo một loại người dùng. Hoặc chúng có thể là các nhà máy trừu tượng, tạo nên các loại người dùng khác nhau.Điều này tùy thuộc vào bạn và những gì hệ thống của bạn cần. Một lần nữa, hãy suy nghĩ về những gì API là cần thiết để đáp ứng các quy tắc kinh doanh của không gian tên miền của bạn: (make($type, $data), makeAdmin($data), makeMember($data)). Cú pháp toán tử variadic của PHP 5.6 sẽ làm cho WAY này sạch hơn để làm việc với btw.

Cares về

  • Làm sáng bóng mới Users

Không quan tâm đến

  • Nguồn dữ liệu để làm những sáng bóng mới Users
  • Những gì bạn làm với các User sau khi nó được thực hiện
  • Lots of stuff khác

tài Gateway/Mapper

Đây có thể là cơ chế bền bỉ thực tế của bạn: nó có thể giao tiếp trực tiếp với một cơ sở dữ liệu quan hệ, sử dụng một Nhà máy và được sử dụng bởi Kho lưu trữ. Nó thực sự tìm nạp DB và ánh xạ dữ liệu vào một định dạng mà Nhà máy có thể tiêu hóa. Nhà máy không nên chịu trách nhiệm về bản đồ này vì nó không có bất kỳ kiến ​​thức nào về định dạng nguồn, chỉ định dạng mà nó cần để tập hợp đối tượng miền. Do đó trách nhiệm lập bản đồ nằm trong Gateway/Mapper.

Cares về

  • Trường hợp User là nhận được vẫn kiên trì đến/lấy ra từ, và làm thế nào
  • dịch dữ liệu từ kiên trì để một cái gì đó một máy muốn
  • lẽ quan tâm đến một Nhà máy

Không quan tâm đến

  • Trình điều khiển lưu trữ cụ thể (ví dụ: MySQL, Postgres) - đây là nơi mà PDO do thỏa thuận hợp
  • Làm một đối tượng mới User
  • Lots of stuff khác

Bây giờ, phải thừa nhận điều này có vẻ cách đơn giản hơn nó thực sự là. Làm thế nào để bạn xử lý trẻ em của tập hợp (ví dụ: nhiều Comments thuộc về một Post)? Bạn đưa những người đó vào giai đoạn Post ở giai đoạn nào? Bạn thậm chí cung cấp cho họ tất cả các thời gian, hoặc chỉ khi bạn yêu cầu một cách rõ ràng (ví dụ như thông qua một cuộc gọi lại?) Đây là những câu hỏi khó mà tôi không có câu trả lời, và một phần được trả lời bởi miền của bạn cần nơi đầu tiên.

ORM là một vấn đề khó giải quyết. Giáo Lý và Eloquent là tuyệt vời, nhưng không thực hiện đúng các mô hình trên. Đó là ok mặc dù. Mẫu trên là hướng dẫn, không phải là quy tắc. Đó là mục tiêu là tập trung vào việc tách mối quan tâm và tập trung trách nhiệm.Nó có thể không cần thiết cho ứng dụng của bạn để có tất cả các lớp này.

Về xác nhận, có hai loại xác nhận:

  1. Mẫu input validation

  2. xác nhận đối tượng miền

Mẫu xác nhận thường được thực hiện tốt nhất bởi một lớp mẫu validator và một số quy tắc được xác định cụ thể cho một biểu mẫu nhất định. Thông thường, bạn có thể xác định các quy tắc đó trong bất kỳ lớp trình tạo biểu mẫu nào bạn có (ví dụ: Form::text('first_name', array('rules' => 'required|alpha'))). Bộ điều khiển nên nhận trình xác thực biểu mẫu dưới dạng phụ thuộc, nhưng không nên thực hiện xác thực thực tế.

Xác thực hợp phần đối tượng miền (ví dụ: bảo vệ tính toàn vẹn của mô hình) có thể trực tiếp trong chính đối tượng miền qua trình cài đặt hoặc có thể hoạt động trong nhà máy. Điều này phụ thuộc hoàn toàn vào cách bạn định xây dựng các đối tượng miền. Cần lưu ý rằng bạn nên có cả hai loại xác nhận hợp lệ: xác thực biểu mẫu để xác thực đầu vào và xác thực đối tượng miền để xác thực tính toàn vẹn dữ liệu khi bạn tạo đối tượng.

+0

Cảm ơn bạn đã phản hồi tuyệt vời! Nó rất hữu ích. :) – ineedhelp

Các vấn đề liên quan