2015-01-04 21 views
7

tôi sử dụng symfony 2.3 và php thuyết 2.Tách logic kinh doanh từ PHP Học thuyết 2

Chương trình có các mô hình sau:

  • thể Order - một đơn đặt hàng tiêu biểu
  • thực thể BadOrderEntry (trường : id, order - unidirectional mối quan hệ một-một với Order, createdAt)
  • nhà máy BadOrderEntryNhà máy sản xuất cho thực thể sáng tạo BadOrderEntry
  • kho chứa BadOrderEntryReposi Tory cho phương pháp tìm kiếm thực thể BadOrderEntry
  • quản lý BadOrderEntryManager cho lưu/chỉnh sửa/xóa các phương pháp của tổ chức BadOrderEntry
  • VÀ CHỦ CLASS BadOrderList - danh sách các đơn đặt hàng xấu, mã của lớp này:

    private $factory; 
    private $repository; 
    private $manager; 
    
    public function __construct(
        BadOrderEntryFactory $f, 
        BadOrderEntryRepository $r, 
        BadOrderEntryManager $m 
    ) { 
        $this->factory = $f; 
        $this->repository = $r; 
        $this->manager = $m; 
    } 
    
    public function has(Order $order) 
    { 
        return $this->repository->existsByOrder($order); 
    } 
    
    public function add(Order $order) 
    { 
        if (! $this->has($order)) { 
         $entry = $this->factory->create($order); 
         $this->manager->save($entry); 
        } 
    } 
    
    public function remove(Order $order) 
    { 
        $entry = $this->repository->findOneByOrder($order); 
        if ($entry !== null) { 
         $this->manager->delete($entry); 
        } 
    } 
    

Tôi thực sự thích thiết kế của lớp này. Tôi nghĩ rất nhiều về nó. Mọi thứ đều tuyệt vời. NHƯNG! Có một vấn đề: hoạt động trong các phương thức thêm và xóa phải được thực hiện trong các giao dịch.

đang giao dịch trong PHP Docrine 2 trông như thế này:

<?php 
$em->getConnection()->beginTransaction(); 
try { 
    //... do some work 
    $em->getConnection()->commit(); 
} catch (Exception $e) { 
    $em->getConnection()->rollback(); 
    throw $e; 
} 

Nhưng làm thế nào tôi có thể gọi mã này bên BadOrderList?

Tôi đã dành rất nhiều thời gian và bị xóa tùy thuộc vào cơ sở dữ liệu (và tương ứng với PHP Doctrine 2), và một lần nữa để tạo nó? Hiện tại, sự phụ thuộc được ẩn trong các lớp BadOrderEntryRepository và BadOrderEntryManager.

Làm cách nào để ẩn phụ thuộc vào cơ chế giao dịch trong lớp BadOrderList?

+0

Thêm quản lý giao dịch của bạn 'quản lý :: add' và 'delete'I cũng khuyên bạn nên suy nghĩ lại bạn thiết kế. Nó không thực sự tốt đẹp. Làm cho mô hình của bạn liên tục độc lập. – Ziumin

+0

@Ziumin Làm cách nào để thêm quản lý giao dịch vào Trình quản lý :: thêm (hoặc xóa)? Vấn đề thiết kế gì? Trình quản lý chỉ đơn giản là lớp trừu tượng bổ sung trên trình quản lý đối tượng doctrine. Nó không tệ và nó không tốt. Nhưng kiểm soát nhiều hơn. – stalxed

+0

Bạn có thể thực hiện theo cách tương tự như bạn đã đề cập trong ví dụ của mình. http://doctrine-orm.readthedocs.org/en/latest/reference/transactions-and-concurrency.html#approach-2-explicitly. Đối với vấn đề thiết kế - tại sao bạn nghĩ danh sách của bạn là đối tượng CHÍNH. Chính cho những gì một phần của bạn kiến ​​trúc? Bạn đã nghĩ về phương pháp và tên lớp? Bạn có thể kiểm tra toàn bộ mô hình của mình mà không có học thuyết không? – Ziumin

Trả lời

4

Sau khi thảo luận của chúng tôi Tôi có một câu trả lời cho câu hỏi của bạn. Câu hỏi thực sự không phải là "Làm thế nào để ẩn sự phụ thuộc vào cơ chế giao dịch trong lớp BadOrderList?", nhưng Làm thế nào để tách một mô hình khỏi một lớp kiên trì? (Doctrine2 trong trường hợp cụ thể đó).

tôi đã cố gắng minh họa gợi ý của tôi với một số mã

class BadOrderEntry 
// Bad - is too bad word to describe an order here. Why is it bad? Is it Declined? Cancelled? 
{ 
    private $order; 
    // some code 
} 
class BadOrderEntryFactory 
{ 
    // If there is not to much processing to build BadOrderEntry better use factory method like BadOrderEntry::fromOrder($order); 
} 
class BadOrderEntryRepository 
{ 
    // here is some read model 
} 
class BadOrderEntryManager 
// ITS a part of our model and shouldn't be coupled to ORM 
{ 
    public function save(BadEntry $be) 
    { 
    // some model events, model actions 
    $this->doSave($be); // here we should hide our storage manipulation 
    } 

    protected function doSave($be) // it can be abstract, but may contain some basic storage actions 
    { 
    } 

    // similar code for delete/remove and other model code 
} 
class ORMBadOrderEntryManager extends BadOrderEntryManager 
// IT'S NOT the part of your model. There is no business logic. There is only persistent logic and transaction manipulation 
{ 
    protected $entityManager; 

    // some constructor to inject doctrine entitymanager 

    protected doSave($be) 
    { 
    $em = $this->entityManager; 
    $em->getConnection()->beginTransaction(); // suspend auto-commit 
    try { 
     $em->persist($be); 
     $em->flush(); 
     $em->getConnection()->commit(); 
    } catch (Exception $e) { 
     $em->getConnection()->rollback(); 
     throw $e; 
    } 
    } 
} 
// You can also implement ODMBadOrderEntryManager, MemcacheBadOrderEntryManager etc. 

Vì vậy, nếu chúng ta nói về cấu trúc thư mục, tất cả các mô hình của bạn có thể được di chuyển ra khỏi bó và sử dụng bất cứ nơi nào. cấu trúc Bundle của bạn sẽ như thế nào:

BadEntryBundle 
| 
+ Entity 
| | 
| --- BadOrderEntryEntity.php 
| 
+ ORM 
| | 
| --- ORMBadOrderEntryManager.php 

Và sau đó bạn sẽ chỉ tiêm ORMBadOrderEntryManager để BadOrderEntryList bạn

+0

Đây thực sự là giải pháp tuyệt vời! Tôi đã thấy một giải pháp tương tự trong JMSPaymentCoreBundle. Nhưng không nghĩ về nó ... Bạn mở mắt ra! Cảm ơn bạn rất nhiều! – stalxed

1

Bạn có thể chuyển đổi lớp học thành một dịch vụ và gọi nó là bất cứ điều gì bạn muốn sau khi tiêm container dịch vụ của bạn bên trong lớp học của bạn. bạn có thể tìm thêm thông tin ở đây về dependency injection:

$injectedContainerOfService->get("id_of_your_service") 
+0

Thx. Đó là giải pháp rất đơn giản và rõ ràng. Nhưng không thực tế/testable/duy trì một. – Ziumin

+0

thực tế của nó và testable nhưng cho rằng bạn nên decouple bộ điều khiển của bạn và biến nó thành một dịch vụ nếu bạn muốn kiểm tra nó – lsroudi

+0

nơi nào bạn nhìn thấy một bộ điều khiển? – Ziumin

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