2012-02-06 33 views
5

Tôi quan tâm đến DDD (Thiết kế Driven Miền) trong những ngày qua, nhưng tôi không thể tìm ra trách nhiệm của người tạo và xác thực các thực thể. Ill phá vỡ câu hỏi này để bao gồm các kịch bản khác nhau.DDD - Trách nhiệm tạo và xác nhận thực thể

  1. Thực thể thường xuyên (Có thể có đối tượng giá trị). Ví dụ: cho phép một người dùng được nhận dạng bằng Email. Tôi có một UserFactory nhận được một mảng dữ liệu (có thể từ POST mẫu), và trả lại cho tôi một UserEntity mới. Nhà máy có nên xác thực tính toàn vẹn của dữ liệu (ví dụ: chuỗi được đưa ra dưới dạng Email là một email thực, mật khẩu trong trường mật khẩu 1 và trường khớp 2 và v.v.) không? Nhà máy có nên xác nhận rằng không có người dùng nào tồn tại (chúng tôi không muốn đăng ký hai người dùng với cùng một email)? Nếu có thì nó có tự làm hay sử dụng UserRepository không?

  2. Thực thể tổng hợp. Giả sử chúng ta có một thực thể Post và các thực thể Comments. Tôi muốn nhận được bài đăng 12 với tất cả các nhận xét của mình, vì vậy tôi thực hiện một số nội dung như

    $ post = $ postRepository-> getById (12);

Cách getById nên được triển khai? như thế này:

public function getById($id) { 
    $postData = $this->magicFetchFromDB($id); 
    $comments = (new CommentRepository())->getForPost(12); 
    return new PostEntity($postData, $comments); 
} 

Hoặc có thể đăng bài chịu trách nhiệm về lười biếng tạo nhận xét của mình, một cái gì đó như:

class PostEntity { 
    public function getComments() { 
     if(is_null($this->_comments)) $this->_comments = (new CommentRepository())->getForPost($this->_id); 
     return $this->_comments; 
    } 
} 

? Tôi bị lạc ở đây và không có đủ thông tin với các ví dụ về DDD trong PHP, vì vậy mọi trợ giúp sẽ được đánh giá cao!

Cảm ơn bạn rất nhiều, skwee.

Trả lời

4
  • Nhà máy cần chỉ quan tâm đến việc tạo đối tượng. Cá nhân tôi thích đặt xác nhận cả trong quan điểm của tôi và trong lớp mô hình. Tôi muốn sử dụng một số thư viện như plugin xác thực của jQuery để thực hiện một số xác nhận cần thiết ở phía máy khách (như kiểm tra nếu các trường bắt buộc có dữ liệu). Và sau đó thực hiện xác nhận "hardcore" trên mô hình. Tôi làm điều này là bằng cách sử dụng một lớp trừu tượng đơn giản BaseEntity mà tất cả các tổ chức mở rộng, và kể từ khi bạn yêu cầu một ví dụ, ở đây là:

    abstract class BaseEntity { 
        public function isValid(); 
    }   
    
    class MyEntity extends BaseEntity { 
        public function isValid() { 
         //actual validation goes here 
        } 
    } 
    

    Bạn cũng có thể tận dụng một lớp helper tĩnh với một số xác nhận cơ bản phương pháp:

    class ValidationHelper { 
        public static function isValidPhonenumber($value) { 
         //check valid phonenumber, using a regex maybe 
        } 
    
        public static function isAlphanumeric($value) { 
         //check for letters and numbers only 
        } 
    } 
    

    Nhiều tranh luận chống lại phương pháp tĩnh bởi vì họ có thể phá vỡ kiểm tra đơn vị, nhưng trong trường hợp này, họ là khá cơ bản và họ không có phụ thuộc bên ngoài, do đó làm cho họ "an toàn hơn".

  • Khi kiểm tra các thực thể hiện có, bạn có thể thực hiện điều này bằng cách truy vấn DB để xem thực thể đã có trước khi thêm/cập nhật hay (đây là cách tôi muốn thực hiện). unique chỉ mục cho các cột không thể lặp lại trong DB và sau đó bọc các truy vấn tạo hoặc cập nhật trong khối try-catch (truy vấn sẽ ném một vi phạm ràng buộc duy nhất, nếu hai người dùng có cùng một e-mail chẳng hạn) và sau đó hiển thị thông báo lỗi thích hợp

  • Về câu hỏi cuối cùng của bạn, nó xuất hiện theo sở thích. Nếu DB của bạn sẽ nhận được một triệu lượt truy cập trong 1 phút thì có thể tốt hơn nếu bạn sử dụng tải chậm để tránh tìm nạp dữ liệu không cần thiết cho đến khi cần. Nhưng nếu cơ sở dữ liệu của bạn là tương đối nhỏ, bạn hoàn toàn có thể sử dụng tải háo hức mà không bị mất quá nhiều hiệu suất. Một lần nữa, đây là vấn đề sở thích cá nhân.

hy vọng một số điều rambling này có ý nghĩa, cổ vũ!

+0

Cảm ơn bạn đã bình luận! A) Tôi không chắc chắn về việc xác thực trong thực thể. Bạn có xem xét xác thực captcha là một phần của logic nghiệp vụ không? Và điều gì sẽ xảy ra nếu tôi có bảng điều khiển quản trị để thêm người dùng theo cách thủ công mà không cần captcha? B) Có, tôi có thể, nhưng câu hỏi là ai có trách nhiệm? Lớp xác nhận? Nhà máy? Kho? C) Ok nhưng nếu tôi có Người dùng có bài đăng có nhận xét, liệu có phải thông minh để tải tất cả dữ liệu này để hiển thị trang tiểu sử người dùng không? –

+1

a) nó phụ thuộc vào nhu cầu của bạn thực sự, tôi đã tìm thấy nó "dễ dàng hơn" để có xác nhận trong thực thể chính nó bằng cách sử dụng các lớp helper. nhưng thêm một lớp xác nhận là hoàn toàn tốt đẹp. b) tôi sẽ nói đó là trách nhiệm của lớp xác nhận. nếu hai Tài khoản không thể có cùng một số và bạn cố gắng thêm một số với một số đã tồn tại, điều đó có nghĩa là thực thể đó là ** không hợp lệ **, hoặc ít nhất đó là những gì tôi nghĩ. – jere

+1

c) điều này cũng phụ thuộc vào những gì bạn muốn. nếu bạn sẽ hiển thị tất cả thông tin đó cùng một lúc trên trang hồ sơ thì có, tải tất cả thông tin trong một cuộc gọi. nhưng nếu bạn hiển thị, cho phép nói, chỉ các bài đăng và khi bạn nhấp vào một bài đăng, bạn nên tải các nhận xét trong thời điểm đó, có thể sử dụng ajax – jere

1

Cách tốt nhất và dễ nhất cho việc này là sử dụng Doctrine2. Có lẽ những giờ đầu tiên sẽ khó khăn, nhưng một khi bạn nắm vững Doctrine2 tất cả các mối quan hệ như vậy và tổng hợp là miếng bánh.

Bạn có thể tìm thấy nhiều thông tin về PHP & DDD hoặc Doctrine2 trên http://giorgiosironi.blogspot.com/ hoặc chỉ bằng cách googling.

RE: Xác thực - xem xét Nguyên tắc về trách nhiệm duy nhất, chúng tôi sử dụng các đối tượng Xác thực. Việc xác nhận có thể phức tạp và có thể yêu cầu các kho lưu trữ hoặc các thực thể khác, do đó, tốt hơn là giữ nó ngoài thực thể - chủ đề của xác nhận hợp lệ để tránh tạo các đối tượng cồng kềnh. Bạn có thể sử dụng mẫu thiết kế của khách truy cập hoặc đặc điểm kỹ thuật.

Có rất nhiều bài đăng khác ở đây về các chủ đề đó - hãy thử sử dụng các từ khóa ở trên.

+0

Tôi đã sử dụng học thuyết lúc đó, không thực sự thích nó, nó lớn và nặng. Tuy nhiên đó là Doctrine2 trước, tôi có thể cho Doctrine một lần nữa. Tuy nhiên tôi vẫn quan tâm nhiều hơn đến cách làm đúng đắn hơn là tìm một giải pháp đã sẵn sàng. Để xác nhận, cảm ơn bạn đã mang SRP! Tôi quên mất nó và không chắc tôi có nên chèn thêm một lớp Validation nữa không, bây giờ tôi chắc rằng tôi cần :) –

+0

Doctrine dựa trên mẫu Active Record, Doctrine2 chính xác là những gì bạn cần để thực hiện DDD dễ dàng hơn. Như tôi đã viết trên một bài tương tự như sau - giải pháp xây dựng tại nhà thường kết thúc như là cơn ác mộng bảo trì và rễ tổng hợp trở nên rất thủ công. Thông thường mỗi AR được thực hiện theo cách khác nhau dựa trên đó nhà phát triển đã làm cho nó. Đã ở đó, tin tôi đi, bạn không muốn đi theo cách đó ... –

+0

Tôi có hội chứng "tái phát minh". Nếu tôi được yêu cầu thực hiện DDD tại nơi làm việc của tôi với lịch trình chặt chẽ, tôi có thể đi với Doctrine. Vì câu hỏi của tôi đã được nêu ra từ dự án cá nhân của tôi, trong đó tôi không có những đường chết nghiêm ngặt, tôi thích học càng nhiều càng tốt bằng cách thực hiện công cụ này. Tôi có một giải pháp tốt đẹp ATM nhưng tôi sợ nó sẽ phá vỡ ngay sau khi Ill cố gắng làm phức tạp nó, vì vậy tôi đang xem xét Doctrine. Ngoài ra AFAIK Doctrine không hỗ trợ lưu trữ không phải DB (tức là dựa trên tệp hoặc cơ sở dữ liệu noSQL), điều này có thể là một vấn đề cho tương lai (tôi chắc chắn viết một trình điều khiển không phải là một vấn đề). –

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