2009-03-07 36 views
15

Tôi hiện đang xây dựng lại hệ thống bán vé chuyên dụng tại nơi làm việc (chủ yếu được sử dụng để hỗ trợ những người có lỗi trong phần cứng viễn thám ...). Dù sao, tôi đã tự hỏi liệu làm rất nhiều hoạt động loại công việc trong một nhà xây dựng của đối tượng là một ý tưởng tốt.Có phải logic nghiệp vụ trong các nhà thầu là một ý tưởng hay không?

Ví dụ, hiện nay là thế này:

$ticket = new SupportTicket(
    $customer, 
    $title, 
    $start_ticket_now, 
    $mail_customer 
); 

ngay khi đối tượng được tạo ra, nó sẽ đặt một hàng vào một cơ sở dữ liệu, đi và gửi cho khách hàng xác nhận e-mail, có thể gửi tin nhắn văn bản cho kỹ thuật viên gần nhất, v.v.

Nhà xây dựng có nên kích hoạt tất cả công việc đó hoặc thứ gì đó tương tự như sau không?

$ticket = new SupportTicket($customer, $title); 
$customer->confirmTicketMailed($ticket); 
$helpdesk->alertNewTicket($ticket); 

Nếu được, các đối tượng đều dựa trên kiểu ActiveRecord.

Tôi đoán đó có thể là vấn đề về ý kiến, nhưng bạn nghĩ điều gì là tốt nhất để làm?

+0

Bạn có thể thấy điều này có liên quan: [Constructors Must Be Code-Free] (http: //www.yegor256. com/2015/05/07/ctors-must-be-code-free.html) – yegor256

Trả lời

38

Nếu hàm tạo thực hiện tất cả các công việc đó thì hàm tạo biết về nhiều đối tượng miền khác. Điều này tạo ra một vấn đề phụ thuộc. Nếu ticket thực sự biết về CustomerHelpDesk? Khi các tính năng mới được thêm vào, không phải là các đối tượng miền mới sẽ được thêm vào luồng công việc và điều đó có nghĩa là số ticket của chúng ta sẽ phải biết về số lượng đối tượng miền ngày càng tăng?

Sự cố với mạng nhện phụ thuộc như thế này là thay đổi mã nguồn thành bất kỳ đối tượng tên miền nào sẽ có tác động đến số kém ticket của chúng tôi. ticket sẽ có rất nhiều kiến ​​thức về hệ thống mà không có vấn đề gì xảy ra, ticket sẽ được tham gia. Bạn sẽ thấy các câu lệnh khó chịu if thu thập bên trong hàm tạo đó, kiểm tra cơ sở dữ liệu cấu hình và trạng thái phiên, và rất nhiều thứ khác. Các ticket sẽ phát triển để trở thành một lớp thần.

Một lý do khác khiến tôi không thích các nhà thầu làm việc là nó làm cho các đối tượng xung quanh họ rất khó kiểm tra. Tôi thích viết rất nhiều đồ vật giả. Khi tôi viết một bài kiểm tra với số customer Tôi muốn chuyển nó một cách giả mạo ticket. Nếu hàm tạo của ticket kiểm soát luồng công việc và đoạn nhảy giữa customer và các đối tượng miền khác, thì có khả năng tôi sẽ không thể thử nghiệm nó để kiểm tra customer.

Tôi khuyên bạn nên đọc The SOLID Principles, một bài báo tôi đã viết vài năm về quản lý các phụ thuộc trong thiết kế hướng đối tượng.

+0

Thiên Chúa nói trực tiếp với Robert C. Martin trả lời câu trả lời của bạn: O –

4

Chia nhỏ mọi thứ. Thực sự, bạn không muốn một vé để biết làm thế nào nó nên gửi e-mail vv Đó là công việc của một dịch vụ như lớp học.

[Cập nhật] Tôi không nghĩ rằng các mẫu nhà máy được đề xuất là tốt cho việc này. Một nhà máy là hữu ích nếu bạn muốn tạo ra các triển khai khác nhau của vé mà không đặt logic này trong bản thân vé (thông qua các nhà xây dựng quá tải chẳng hạn).

Hãy xem khái niệm Dịch vụ được đề xuất trong Thiết kế theo hướng miền.

Dịch vụ: Khi một thao tác không thuộc về bất kỳ đối tượng nào. Theo các đường nét tự nhiên của vấn đề, bạn có thể thực hiện các hoạt động này trong các dịch vụ. Khái niệm dịch vụ được gọi là "Chế tạo thuần túy" trong GRASP.

4

Vấn đề, từ quan điểm thiết kế OO, không quá nhiều cho dù chức năng đó nên được thực hiện trong một hàm khởi tạo (trái ngược với các phương thức khác trong lớp đó), nhưng lớp SupportTicket có biết cách thực hiện hay không tất cả những điều đó.

Tóm lại, lớp SupportTicket nên mô hình hóa một vé hỗ trợ và chỉ có một vé hỗ trợ. Tạo email, biết cách gửi email đó cho khách hàng, xếp hàng vé để xử lý, v.v. là tất cả các khối chức năng mà bạn nên chuyển từ lớp SupportTicket của bạn và đóng gói ở nơi khác. Các lợi ích của việc này bao gồm khớp nối thấp hơn, sự gắn kết cao hơn và khả năng kiểm tra được cải thiện.

Hãy xem qua số Single Responsibility Principle, giải thích lợi ích của việc này. Đặc biệt, this blog là một nơi tốt để đọc về SRP và các nguyên tắc cốt lõi khác của thiết kế OO tốt.

+0

Điều này đánh vào móng trên đầu, cho dù bạn sử dụng một nhà máy (như các bài viết khác đề cập đến) hay không là không liên quan. – Egwor

2

Câu trả lời ngắn gọn là không.

Trong thiết kế phần cứng, chúng tôi đã từng có câu nói "Đừng đặt cổng trên đồng hồ hoặc đường đặt lại - nó che khuất logic." Điều tương tự cũng áp dụng ở đây vì cùng một lý do.

Câu trả lời dài hơn sẽ phải chờ, nhưng hãy xem "ScreetchinglyObvious Code".

+0

Dựa trên bối cảnh ở đây, người dùng "Alistair" rất có thể là [Alistair Cockburn] (https://en.wikipedia.org/wiki/Alistair_Cockburn). –

1

Thực ra tôi chưa bao giờ hài lòng với bất kỳ câu trả lời nào có sẵn, nhưng hãy nhìn vào chúng. Các lựa chọn được xây dựng xung quanh hai câu hỏi đánh giá:

E1. Kiến thức thuộc về logic kinh doanh ở đâu?

E2. Trình đọc mã tiếp theo sẽ ở đâu? (Screechingly Obvious Code)

Một số lựa chọn:

  • Trong mã client (đối tượng mà không "SupportTicket mới"). Nó có lẽ không/không nên biết logic kinh doanh, rõ ràng, nếu không bạn sẽ không muốn tạo ra nhà xây dựng ưa thích đó. Nếu nó là nơi phù hợp với logic kinh doanh, sau đó nó nên nói:

    $ticket = new SupportTicket($customer, $title); 
    
    handleNewSupportTicket($ticket, ...other parameters...) 
    

    ở đâu, để bảo vệ E2, "handlenewSupportTicket" là nơi mà logic kinh doanh được định nghĩa (và các lập trình viên tiếp theo có thể dễ dàng tìm nó).

  • Trong các đối tượng hỗ trợ vé đối tượng, dưới dạng cuộc gọi kinh doanh riêng biệt. Cá nhân, tôi không thực sự hài lòng với điều này, bởi vì đó là hai cuộc gọi từ mã khách hàng, nơi mà suy nghĩ tinh thần là 1 điều.

    $ticket = new SupportTicket($customer, $title); 
    
    $ticket -> handleNewSupportTicket(...other parameters...) 
    
  • Trong lớp vé hỗ trợ.Ở đây người ta cho rằng logic nghiệp vụ nằm trong khu vực Hỗ trợ vé, nhưng vì vé hỗ trợ mới hoàn toàn cần phải được xử lý ngay lập tức và không muộn hơn, nhiệm vụ quan trọng này không thể để lại cho trí tưởng tượng của bất kỳ ai hoặc mã máy khách. Tôi chỉ biết làm thế nào để mã hóa các phương thức lớp trong Smalltalk, nhưng tôi sẽ mất một đâm vào pseudo-code:

    $ticket = SupportTicket.createAndHandleNewSupportTicket(...other parameters...) 
    

    Giả sử rằng các mã khách hàng cần xử lý để vé mới cho các mục đích khác (nếu không thì "$ ticket = "sẽ biến mất).

    Tôi không quá ngây thơ về điều này, bởi vì các lập trình viên khác không tìm thấy nó tự nhiên để tìm logic nghiệp vụ trong lớp hoặc phương pháp tĩnh. Nhưng đó là lựa chọn thứ ba.

  • Lựa chọn thứ tư duy nhất là nếu có một nơi khác mà logic kinh doanh vui vẻ cư trú và các lập trình viên khác sẽ tìm kiếm nó một cách tự nhiên, trong trường hợp này nó đi vào lớp/chức năng tĩnh ở đó.

    $ticket = SupportTicketBusinessLogic.createAndHandleNewSupportTicket(...other params...) 
    

    nơi mà lớp/chức năng tĩnh thực hiện nhiều cuộc gọi cần thiết. (Nhưng bây giờ chúng ta một lần nữa có khả năng rằng vé có thể được xây dựng và không được xử lý đúng cách: (

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