2015-11-29 19 views
7

Tôi có một số nhầm lẫn về việc sử dụng Bộ điều khiển với Mô hình Kho lưu trữ trong khi vẫn duy trì Nguyên tắc RẮN. Xem xét, tôi có hai loại Báo giáNguyên tắc RẮN Trong Laravel với Mô hình Kho lưu trữ

  1. Báo giá thương mại
  2. Báo giá cá nhân

Và có một cơ hội cao loại mới của trích dẫn trong tương lai. Mỗi Báo giá có các lĩnh vực khác nhau, logic kinh doanh nhưng họ chia sẻ nhiều chức năng phổ biến. Vì vậy, tôi đã tạo ra một QuotationInterface

Báo giá inteface

interface QuotationInterface 
{ 
    public function save(array $data); 

} 

lớp Báo giá mà thực hiện giao diện

class CommercialQuotation implements QuotationInterface 
{ 
    public function(array $data) 
    { 
     // save commercial quotation 
    } 
} 

class PrivateQuotation implements QuotationInterface 
{ 
    public function(array $data) 
    { 
    // save Private quotation 
    } 
} 

Báo giá Repository

class QuotationRepository 
{ 
    public function save(array $data, QuotationInterface $quotation) 
    { 
     $quotation->save($data); 
    } 
} 

QotationController

public function store(Resource $resource) 
{ 

    $inputs = $resource->all(); 

    /** 
    * Clearly here Open/Close Principle is broken 
    */ 

    if ($inputs['type'] == 'private'){ 
     $quotation = new PrivateQuotation;; 
    } 
    else if($inputs['type'] == 'commercial'){ 
     $quotation = new CommercialQuotation; 
    } 

    $this->repo->save($inputs, $quotation); 
} 

đây trong QuotationController của tôi, nó đang vi phạm rõ ràng Mở/Đóng Nguyên tắc ..

có phải là một ý tưởng tốt để tạo một điều khiển đối với từng loại ngoặc kép (có thể Hơn 10 ngày, ai biết?) để tránh vi phạm OCP hoặc thiết kế của tôi là sai? Bất kỳ đề xuất, mẹo thay đổi thiết kế, tài nguyên đều được chào đón.

LƯU Ý: Bộ điều khiển báo giá của tôi sẽ có nhiều chức năng khác ngoại trừ chức năng lưu.

Trả lời

5

Nếu bạn đang đi về phía trước con đường bạn đã thể hiện, tôi khuyên bạn nên sử dụng một bộ điều khiển duy nhất cho những trích dẫn của bạn và sử dụng một mẫu thiết kếFactory để tạo $quotation đối tượng của bạn

Ví dụ, với một nhà máy đơn giản như thế này:

//FACTORY CLASS 
abstract class QuotationFactory 
{ 
    /** return QuotationInterface */ 
    public static function createQuotation($type) 
    { 
     switch($type) 
     { 
      CASE "private": 
       return new PrivateQuotation(); 
      break; 

      CASE "commercial": 
       return new CommercialQuotation(); 
      break;  
     } 
    } 
} 

bạn có thể sử dụng các nhà máy từ phương pháp bạn điều khiển:

//YOUR CONTROLLER'S METHOD 
public function store(Resource $resource) 
{ 
    $inputs = $resource->all(); 

    //delegate objects creation to factory class 
    $quotation = QuotationFactory::createQuotation($inputs['type']); 

    $this->repo->save($inputs, $quotation); 
} 

Bằng cách này bạn sẽ không vi phạm nguyên tắc mở/đóng trong bộ điều khiển của bạn, bởi vì khi bạn thêm các trích dẫn, bạn sẽ chỉ cần sửa đổi phương thức của nhà máy (thêm trường hợp vào câu lệnh switch), và nó sẽ trả về QuotationFactory đối tượng ở bất cứ nơi nào cần thiết.

này cũng sẽ giữ mã của bạn DRYRẮN bởi vì bạn không phải lặp lại nếu/báo cáo khác để tạo các đối tượng của bạn trong các phương pháp điều khiển của bạn như bạn ủy responsability sáng tạo của các đối tượng đến một cụ thể lớp nhà máy

Như đã chỉ ra chính xác trong các bình luận bên dưới, nhà máy đơn giản sẽ giúp bạn tránh nguyên tắc mở/đóng trong bộ điều khiển của bạn nhưng hãy lưu ý rằng, từ quan điểm chung hơn, bản thân Simple Factory vốn đã vi phạm OCP vì nó sử dụng trường hợp chuyển đổi.

Dù sao, từ những gì tôi thấy trong ứng dụng của bạn, nhà máy đơn giản có thể là giải pháp tốt, vì mối quan tâm chính của bạn là xây dựng trong nhiều trường hợp từ một loại biến. Vì vậy, bằng cách sử dụng nhà máy đơn giản, bạn có thể 'ẩn' quá trình này của việc tạo ra các đối tượng vào nhà máy và nhận được các trường hợp bạn cần trong bộ điều khiển của bạn. Vì vậy, bạn đang vi phạm OCP chỉ bên trong nhà máy trong trường hợp chuyển đổi, nhưng tôi nghĩ rằng đây có thể là một beareble thương mại-off

+1

Tôi sẽ làm theo ví dụ của bạn. Cảm ơn. –

+0

Sự cần thiết phải sửa đổi nhà máy là một vi phạm cổ điển của Nguyên tắc Mở/Đóng: nó có nghĩa là mã không bị đóng để sửa đổi. Trong thực tế, chuyển đổi/trường hợp luôn luôn là một vi phạm của OCP, đó là lý do tại sao nó không được bao gồm trong mô hình thiết kế phương pháp nhà máy GoF. Mẫu thiết kế dựa trên đa hình. – jaco0646

+0

@ jaco0646: Các mẫu thiết kế không phải là quy tắc tuyệt đối, nhưng đó là định dạng nhập để đánh giá chúng theo tình hình thực tế. Trong một trường hợp như thế này, một nhà máy đơn giản có thể là một giải pháp tốt.Như tôi đã đề ra ở cuối bài viết của tôi, tùy thuộc vào kiến ​​trúc của ứng dụng, op có thể thực hiện một nhà máy trừu tượng hoặc một phương thức factory – Moppo

1

Tôi nghĩ điều này chủ yếu phụ thuộc vào phạm vi đơn đăng ký của bạn. Trong thế giới PHP những ngày này, mọi người rất tức giận với các câu lệnh if/else :). Tuy nhiên, nếu điều đó làm việc cho ứng dụng của bạn và có vẻ hợp lý trong phạm vi ngữ cảnh CỦA BẠN, tôi nghĩ điều đó là tốt.

Thay đổi doanh nghiệp và thay đổi kinh doanh không phải lúc nào cũng dễ dàng lên kế hoạch. Bạn chỉ có thể cố gắng làm cho những thay đổi đó dễ dàng hơn khi chúng phát sinh.

Điều đó đang được nói, các lớp học rẻ và tôi nghĩ rằng có các lớp học riêng biệt tại thời điểm này (và trong tương lai) là rất hợp lý. Nếu các yêu cầu cho từng loại báo giá mở rộng, bạn sẽ ở trạng thái tốt và tôi không nghĩ rằng bạn đang trừu tượng cho đến nay mã của bạn sẽ khó hiểu.

+0

Hmm .. Tôi nghĩ rằng bạn là đúng .. Không có bất kỳ câu trả lời chính xác tuyệt đối của câu hỏi này và những gì bạn nói là hợp lý. Tôi cần phải cố gắng hết sức để gắn bó với thực hành tốt nhất nhưng đôi khi cần phải đi offtrack do bối cảnh ứng dụng. –

+0

Câu trả lời này rất chung chung ... không thể sao chép và dán vào mọi câu hỏi mẫu thiết kế PHP trên SO? – jaco0646

+0

Chung hay không, đó là thực tế. Thực tế là bạn không thể áp dụng một sự thật tuyệt đối cho loại câu hỏi này. Có nhiều cách để làm việc, và không phải tất cả chúng đều được áp dụng trong mọi ngữ cảnh. Và tôi nghĩ thật tốt khi nghĩ về những loại câu hỏi này, và hơn nữa, nhận ra rằng phương pháp tiếp cận đó có thể khác nhau trong bất kỳ ngữ cảnh cụ thể nào. – djt

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