Tôi nên đầu tư bao nhiêu công sức vào việc tạo ra các thiết kế ghép lỏng lẻo?


10

Tôi hiện đang tìm hiểu về các mẫu thiết kế.

Tôi nghĩ rằng hầu hết mọi người sẽ đồng ý rằng những mẫu này là những công cụ tuyệt vời, nhưng nên được sử dụng có chừng mực và không phải là câu trả lời cho mọi thứ. Sử dụng chúng quá nhiều sẽ làm phức tạp quá mức ứng dụng với rất ít lợi ích. Các mẫu chỉ nên được sử dụng khi chúng có thể là giải pháp tốt nhất hoặc trợ giúp trong việc tạo ra một giải pháp tốt (bạn có đồng ý không?).

Với ý nghĩ này:

Cuốn sách tôi đang đọc (Các mẫu thiết kế đầu tiên) thường nhấn mạnh tầm quan trọng của khớp nối lỏng lẻo . Khớp nối lỏng lẻo này được thực hiện theo các nguyên tắc như 'chương trình cho giao diện, không phải là triển khai' và 'gói gọn những gì thay đổi'.

Về cơ bản, hầu hết các mẫu tôi đã học cho đến nay tồn tại chủ yếu là cho phép các thiết kế được ghép lỏng lẻo, và do đó linh hoạt hơn.

Tôi hiểu tầm quan trọng và lợi ích của khớp nối lỏng lẻo.

Nhưng câu hỏi của tôi là, một người thực sự nên đầu tư bao nhiêu vào việc tạo ra các thiết kế linh hoạt, kết hợp lỏng lẻo?

Những người phản đối các mẫu thiết kế nói rằng chi phí cho việc sử dụng các mẫu này thường vượt trội hơn lợi ích. Bạn đầu tư nhiều thời gian vào việc tạo ra một thiết kế ghép lỏng lẻo bằng cách sử dụng một số mẫu, trong thực tế - khớp nối lỏng lẻo, "lập trình cho giao diện, không phải là triển khai" và tất cả các nguyên tắc này - có thể không thực sự quan trọng.

Những gì tôi muốn biết, là tôi thực sự cần bao nhiêu nỗ lực để tạo ra các mức độ trừu tượng và thiết kế bổ sung, chỉ cho phép ứng dụng của tôi tuân theo các nguyên tắc OO như khớp nối lỏng lẻo, lập trình cho giao diện, v.v. nó không Bao nhiêu nỗ lực tôi nên đặt trong này?


Một số người dành toàn bộ cuộc đời cho nó, Kent Beck chẳng hạn, những người đánh giá cao nó sẽ thấy nỗ lực của bạn.
Niing

Câu trả lời:


14

Câu trả lời mệt mỏi: bạn càng làm điều đó, nó càng ít nỗ lực.

Về cơ bản, xây dựng mã ghép lỏng lẻo không thực sự khó. Đào tạo tâm trí của bạn để suy nghĩ về mặt khớp nối lỏng lẻo, mặt khác, là. Và, tốt, tôi tin rằng nó hoàn toàn xứng đáng.

Giả sử bạn nhận một công việc sử dụng phương pháp lặp để phát triển phần mềm, như đã được hầu hết mọi người khuyên dùng trong 20 năm qua. Bạn xây dựng một cái gì đó hoạt động rất đẹp trong Lặp lại 1. Trong Lặp lại 2, bạn xây dựng trên nó, thêm một số tính năng mới và hơi uốn cong một hoặc hai điều một chút khi chúng không phù hợp với khái niệm lặp 1 của bạn về cách mọi thứ hoạt động . Bây giờ đến lần lặp 3, và bạn tìm ra các yêu cầu yêu cầu bạn suy nghĩ lại về kiến ​​trúc cơ bản của bạn. Làm thế nào để bạn xé mã của bạn ra và xây dựng lại nó mà không quay lại hình vuông?

Điều này xảy ra. Rất nhiều. Nó hoặc làm cho các dự án chạy muộn, hoặc nó làm cho mọi người quá sợ hãi để làm những gì cần phải làm trong các lần lặp lại sau này. Trong trường hợp tốt nhất, bạn nhận được một Big Ball of Mud. Những thứ như khớp nối lỏng lẻo và nguyên tắc trách nhiệm duy nhất giảm thiểu những vấn đề này một cách lớn. Đó là lý do tại sao các nguyên tắc RẮN được chào mời - chúng thực sự có ích.

Và bạn sẽ thấy rằng sau khi bạn có một vài thiết kế được ghép lỏng lẻo dưới thắt lưng, nó sẽ bắt đầu xuất hiện một cách tự nhiên. Các mẫu là những thứ mà mọi người tìm thấy đã làm việc cho họ, vì vậy họ đã ghi lại chúng. Chúng là những công cụ hữu ích cũng tự nhiên đến với thời gian.


5

Số lượng nỗ lực cần thiết không phải lúc nào cũng sẽ cho bạn biết đủ; Tôi nghĩ rằng một biện pháp tốt hơn sẽ là nỗ lực để tỷ lệ hoàn trả. Nhưng việc tìm ra mức chi trả có thể không phải lúc nào cũng đơn giản và không có lỗi.

Điều cần lưu ý với các mẫu tăng tính linh hoạt là tốn một số nỗ lực để đặt chúng vào, và trừ khi bạn có thể thấy chính xác lý do tại sao bạn cần chúng, cuối cùng bạn có thể gặp rắc rối trong mã, nhưng không bao giờ sử dụng nó. Nếu tính linh hoạt không bao giờ bị uốn cong, nó cũng có thể không ở đó.

Có một điều mà bạn nên luôn luôn làm (hoặc gần với nó nhất có thể): biến các thành phần riêng lẻ của phần mềm của bạn (các đối tượng cho OOP, các chức năng để lập trình theo chức năng hoặc thủ tục) thành các hộp đen. Hộp đen là thứ mà bên trong (thực hiện) chúng ta không biết hoặc không quan tâm.

Nếu chúng ta không biết hoặc quan tâm đến cách thức hoạt động của nó, thì chúng ta sẽ không thử sử dụng bất cứ thứ gì ngoại trừ giao diện, vì vậy nếu việc triển khai thay đổi mà không thay đổi giao diện, điều đó chỉ quan trọng bên trong hộp đen - không có gì bên ngoài nó có thể bị ảnh hưởng. Nó cũng làm cho việc suy nghĩ về chương trình trở nên dễ dàng hơn, bởi vì bạn không phải giữ từng chi tiết của toàn bộ chương trình trong đầu. Càng nhiều chi tiết bạn có thể quên một cách hợp pháp, càng có nhiều chỗ trong đầu của bạn cho các chi tiết quan trọng.

Tôi nghĩ rằng bạn đã hiểu nhầm sự phản đối đối với các mẫu thiết kế; Tôi không phải là một fan hâm mộ của họ, nhưng tôi rất thích nguyên tắc ghép lỏng và lập trình vào một giao diện. Sự phản đối mạnh mẽ nhất của tôi đối với họ là chúng được trình bày dưới dạng một giải pháp đóng gói sẵn không khuyến khích hiểu các nguyên tắc đằng sau chúng, mà chỉ khuyến khích ghi nhớ các chi tiết. Tôi sẽ không khuyên bạn không nên nghiên cứu chúng, nhưng khi bạn làm vậy, hãy nhớ rằng việc hiểu các nguyên tắc đằng sau chúng quan trọng hơn các chi tiết cụ thể của bất kỳ mẫu cụ thể nào.

Một trong những sự phản đối đối với các mẫu thiết kế là chúng 'rõ ràng' hoặc 'Tôi đã sử dụng chúng trước khi tôi nghe về chúng, không phải bởi cái tên đó'. Lý do mọi người có thể đưa ra những phản đối đó, hoặc người khởi tạo các mẫu thiết kế có thể đưa ra chúng ngay từ đầu, là vì họ hiểu các nguyên tắc đằng sau chúng.

Sử dụng hộp đen sắp xếp mã của bạn theo cách lành mạnh và chúng thường không tốn nhiều tiền (nếu có); sử dụng chúng ở mọi nơi Sử dụng một mẫu thiết kế hoặc một số kỹ thuật khác có thêm một lớp trừu tượng hoặc làm phức tạp mọi thứ có chi phí; không bao giờ sử dụng chúng chỉ vì chúng đẹp hoặc gọn gàng hoặc thông minh; sử dụng chúng khi chúng phù hợp với vấn đề và chi phí đáng để trả để nhận được lợi ích.


4

Câu hỏi của bạn dường như đánh đồng sự ghép lỏng lẻo với Mẫu thiết kế, nhưng chúng thực sự riêng biệt, nhưng những thứ liên quan.

Khớp nối lỏng lẻo là một mối quan tâm cơ bản trong lập trình. Ngay khi chúng tôi rời khỏi mã máy và sang các ngôn ngữ tượng trưng, ​​các chương trình đã trở nên lỏng lẻo kết hợp với việc thực hiện chúng. Vân vân.

Bản thân OO về cơ bản là một mô hình để tạo ra các thành phần ghép lỏng lẻo. Đóng gói làm cho bên trong của các đối tượng lỏng lẻo kết hợp với các đối tượng khác. Lập trình hàm có thể thậm chí còn hơn thế, bởi vì việc thực thi chức năng được kết hợp lỏng lẻo với việc thực hiện các chức năng khác ở mức cực đoan.

Hầu như theo định nghĩa, bất kỳ thiết kế nào bạn làm sẽ liên quan đến khớp nối lỏng lẻo. Có nhiều cách bạn có thể sắp xếp để có những thứ được ghép chặt vô tình, nhưng tôi chỉ thấy một vài trường hợp ai đó thực sự thiết kế một hệ thống để được kết nối chặt chẽ hơn .

. và tái sử dụng trong nhiều bối cảnh.)


3

Các mẫu chỉ nên được sử dụng khi chúng có thể là giải pháp tốt nhất hoặc trợ giúp trong việc tạo ra một giải pháp tốt (bạn có đồng ý không?).

Tôi thấy các mẫu thiết kế đúng như chi tiết thực hiện. Nếu bạn ghi lại các API công khai và lập trình cho tài liệu đó, nói chung, nó sẽ không thành vấn đề (hoặc ảnh hưởng đến bạn nhiều) khi bạn có các mẫu thiết kế. Đó là, bạn không đi "Tôi có một mẫu cầu ở đây và tôi sẽ triển khai một khách truy cập trên đầu trang". Thay vào đó, "lớp này sẽ có các triển khai khác nhau trên các hệ điều hành khác nhau nên nó sẽ được thực hiện bằng cách sử dụng một mẫu cầu". Sau đó, khi bạn sử dụng nó, bạn thờ ơ với việc nó được triển khai như một cây cầu - bởi vì bạn nhìn vào API công khai, không phải là một mẫu cầu nối.

người ta thực sự nên đầu tư bao nhiêu vào việc tạo ra các thiết kế linh hoạt, kết hợp lỏng lẻo?

Khớp nối lỏng lẻo có thể đạt được bằng cách tuân theo một bộ quy tắc đơn giản. Nếu bạn tôn trọng những điều này, mã của bạn sẽ được kết nối một cách lỏng lẻo, khi bạn viết nó (tức là bất kỳ nỗ lực nào đã là một phần của quá trình phát triển).

Trong số các quy tắc (không phải là một danh sách đầy đủ):

  • xác định giao diện của bạn bằng cách suy nghĩ (hoặc viết) mã máy khách (cách lớp sẽ được sử dụng), chứ không phải lớp sẽ làm gì (nghĩa là mong muốn giao diện, không phải thực hiện)
  • "nói, đừng hỏi"
  • xây dựng các đối tượng từ các phần đã được tạo
  • truyền vào hàm tạo các đối tượng thực tế bạn sẽ sử dụng (không phải nhà máy cho các thành viên, tham số cho nhà máy của tham số hoặc bất cứ thứ gì tương tự).
  • DRY (nếu bạn có hai dòng xuất hiện theo cùng một thứ tự ở hai nơi, hãy trích xuất chúng thành một hàm riêng biệt, v.v.).
  • Nếu việc tạo một đối tượng là một hoạt động phức tạp hơn, hãy thực hiện việc tạo các phần trung gian như một phương thức / lớp của nhà máy (tức là không có trong phần thân của hàm tạo).
  • YAGNI (tạo ra những thứ bạn cần, không phải trước đây).

Các quy tắc này được tuân theo khác nhau, tùy thuộc vào ngôn ngữ, phương pháp phát triển được theo sau bởi nhóm của bạn (ví dụ TDD), các ràng buộc về ngân sách thời gian, v.v.

Ví dụ, trong Java, cách tốt nhất là xác định giao diện của bạn là một interfacevà viết mã máy khách trên đó (sau đó, khởi tạo giao diện với một lớp triển khai).

Mặt khác, trong C ++, bạn không có giao diện, vì vậy bạn chỉ có thể viết giao diện dưới dạng một lớp cơ sở trừu tượng; Vì trong C ++, bạn chỉ sử dụng tính kế thừa khi bạn có yêu cầu cao đối với nó (và do đó tránh được các chức năng ảo không cần thiết), nên có thể bạn sẽ không xác định giao diện riêng, chỉ là tiêu đề lớp).

Những người phản đối các mẫu thiết kế nói rằng chi phí cho việc sử dụng các mẫu này thường vượt trội hơn lợi ích.

Tôi nghĩ họ đang làm sai. Nếu bạn viết mã được ghép lỏng lẻo (và DRY), việc tích hợp các mẫu thiết kế vào nó đi kèm với nỗ lực tối thiểu. Nếu không, bạn sẽ phải điều chỉnh mã của mình để thực hiện một mẫu thiết kế.

Nếu bạn phải thực hiện nhiều thay đổi để triển khai một mẫu thiết kế, thì vấn đề của bạn không phải là mẫu thiết kế - đó là cơ sở mã của bạn là nguyên khối và được liên kết chặt chẽ. Đây là một vấn đề thiết kế xấu / tối ưu, không phải là một vấn đề mẫu thiết kế.

Những gì tôi muốn biết, là tôi thực sự cần bao nhiêu nỗ lực để tạo ra các mức độ trừu tượng và thiết kế bổ sung, chỉ cho phép ứng dụng của tôi tuân theo các nguyên tắc OO như khớp nối lỏng lẻo, lập trình cho giao diện, v.v. nó không Bao nhiêu nỗ lực tôi nên đặt trong này?

Các câu hỏi của bạn đưa ra giả định (không nói) rằng lợi ích duy nhất của khớp nối lỏng lẻo là khả năng dễ dàng thực hiện các mẫu thiết kế. Không phải vậy.

Trong số những lợi ích của khớp nối lỏng lẻo là:

  • tái cấu trúc và thiết kế lại linh hoạt
  • nỗ lực ít lãng phí
  • khả năng kiểm tra
  • tăng khả năng sử dụng lại mã
  • thiết kế đơn giản
  • dành ít thời gian hơn cho trình gỡ lỗi

... và một vài người khác không nghĩ đến tôi ngay bây giờ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.