Chúng ta nên viết thiết kế kiến ​​trúc chi tiết hay chỉ là một phác thảo khi thiết kế một chương trình?


8

Khi tôi đang thiết kế cho một nhiệm vụ, tôi tiếp tục chiến đấu với cảm giác khó chịu này, ngoài việc là một phác thảo chung, cuối cùng nó sẽ bị bỏ qua ít nhiều. Tôi sẽ cho bạn một ví dụ:

Tôi đã viết một frontend cho một thiết bị có hoạt động đọc / ghi. Nó có ý nghĩa hoàn hảo trong sơ đồ lớp để cung cấp cho nó chức năng đọc và ghi. Tuy nhiên, khi bắt đầu thực sự viết chúng, tôi nhận ra rằng chúng có cùng một chức năng chỉ với một dòng mã được thay đổi (đọc và gọi hàm viết), vì vậy để tránh trùng lặp mã, tôi đã kết thúc việc thực hiện một hàm do_io với một tham số phân biệt giữa hoạt động. Tạm biệt thiết kế ban đầu.

Đây không phải là một sự thay đổi khủng khiếp, nhưng nó cũng xảy ra thường xuyên và có thể xảy ra ở những phần quan trọng hơn của chương trình, vì vậy tôi không thể tự hỏi liệu có một điểm nào để thiết kế chi tiết hơn một phác thảo chung, ít nhất là khi nó nói đến kiến ​​trúc của chương trình (rõ ràng khi bạn chỉ định API, bạn phải đánh vần mọi thứ).

Đây có thể chỉ là kết quả của sự thiếu kinh nghiệm của tôi khi thiết kế, nhưng mặt khác, chúng tôi có những phương pháp nhanh nhẹn nói rằng "chúng tôi từ bỏ kế hoạch từ xa, mọi thứ sẽ thay đổi trong vài ngày nữa", thường là vậy tôi cảm thấy thế nào

Vì vậy, chính xác tôi nên "sử dụng" thiết kế như thế nào?


1
Các do_iodường như là một chi tiết thực hiện nội bộ của lớp đó. Giao diện công cộng sẽ và có lẽ vẫn nên read(...)write(...)vì nó dài dòng hơn nhiều về ý định của cuộc gọi.
Julian S.

Câu trả lời:


6

Nếu nó có ý nghĩa hoàn hảo để cung cấp các hoạt động đọc và viết, tại sao loại bỏ chúng?

Từ quan điểm người dùng nó vẫn có ý nghĩa hoàn hảo. Các chi tiết thực hiện không nên can thiệp vào một giao diện được cung cấp.

Những gì bạn có thể làm là tạo một do_io nội bộ được gọi bằng cách đọc và viết.

Cuối cùng, quá trình thiết kế tuân theo các bước sau:

  • xác định giao diện
  • vẽ một thiết kế thô
  • tinh chỉnh mà không thay đổi giao diện đã thỏa thuận

1
+1 quyết định "Tối ưu hóa" để tránh trùng lặp mã không nhất thiết phải yêu cầu thay đổi thiết kế ban đầu.
Marjan Venema

4

Thiết kế kiến ​​trúc của một chương trình phát triển theo thời gian. Tôi không nghĩ ngay từ đầu bạn có mọi thông tin bạn sẽ cần để có một thiết kế chính xác.

Vì vậy, nếu bạn gắn bó với thiết kế mà bạn nghĩ lúc đầu có lẽ bạn sẽ tự giới hạn mình.

Trừ khi bạn đang tạo một api công khai, tôi nghĩ không sao để thay đổi thiết kế trên đường đi.

Ngoài ra, một trong những điều tốt nhất để làm là đầu tư vào một công cụ có thể trích xuất thiết kế từ mã (như NDepend cho C #)


2

Agile tuyên bố sẽ trả lời vấn đề này, với một số thành công, tuy nhiên Fred Brooks đã có câu trả lời 40 năm trước, khi ông viết "Viết một để ném đi, bởi vì dù sao bạn cũng sẽ". Những người không nghiên cứu lịch sử sẽ cam chịu lặp lại nó.

Vì vậy, những gì cần làm là coi thiết kế như một kế hoạch, được thực hiện cho mục đích duy nhất là thay đổi nó. Thiết kế không thể thay đổi là cam chịu. Bạn phải chuẩn bị để vứt bỏ những cái xấu.

Nếu thiết kế là một trong những API công khai, giao diện tương tự, thì cần phải cẩn thận vì chi phí thay đổi cao, tuy nhiên, việc không thể thay đổi sẽ khiến nó thất bại.

Đừng trong một giây nghĩ rằng bạn đủ tốt và biết đủ để có được nó ngay lần thứ nhất, thứ hai hoặc thậm chí thứ ba.


2

Đó là một thực tế của cuộc sống trong hầu hết các dự án thực tế mà mọi thứ thay đổi:

  • (như bạn đã lưu ý) môi trường / nền tảng / API mà chương trình sẽ sử dụng có thể khác với giả định ban đầu
  • các yêu cầu có thể thay đổi tại bất kỳ điểm nào
  • thị trường / thế giới xung quanh có thể thay đổi, làm lỗi thời một số yêu cầu (hoặc toàn bộ dự án)
  • ...

Đây là lý do tại sao các phương pháp Agile phản đối Big Design Up Front, bởi vì nó chỉ mang lại cảm giác an toàn sai lầm, liên quan đến rất nhiều nỗ lực vô ích và khiến việc thích nghi với những thay đổi không thể tránh khỏi trở nên khó khăn hơn.

Tuy nhiên, Agile không bằng "từ bỏ kế hoạch tiến xa" . Các phương pháp nhanh nhẹn liên quan đến số lượng cần thiết của kế hoạch cẩn thận và chu đáo, không còn nữa. Họ rất kỷ luật và khác với "mã hóa cao bồi". Thực hiện đúng số lượng thiết kế là một nỗ lực liên tục để tìm sự cân bằng phù hợp giữa quá mức và thiếu. Nhưng IMHO tốt hơn là sai một chút về phía quá nhiều, hơn là làm quá ít.

Thiết kế ban đầu không nên cố gắng bao quát mọi thứ, nhưng sẽ mang lại cho bạn cảm giác an toàn rằng bạn biết cách tiến hành triển khai, bạn có câu trả lời cho các câu hỏi cơ bản về kiến ​​trúc và bạn có một mô hình tinh thần về cách sử dụng đã biết trường hợp đang đi làm trong cuộc sống thực. Trong khung nhìn Agile, thử nghiệm thực sự của một thiết kế đang được triển khai, do đó, có thể bắt đầu viết mã ngay cả trong giai đoạn thiết kế, chỉ để có cảm giác về thiết kế được hình dung như thế nào, hoặc nhanh chóng xác định nguyên mẫu / xác nhận một số giả định . Lưu ý rằng hầu hết những công việc ban đầu này sẽ bị vứt đi một khi câu trả lời cho câu hỏi đã cho được xác định. Gần như luôn luôn là một điều xấu khi bắt đầu xây dựng một ứng dụng sản xuất thực sự từ một nguyên mẫu ban đầu.

Và cũng có thể quay lại và sửa đổi thiết kế nếu bạn thực hiện một nhận thức quan trọng mới trong quá trình thực hiện. Đây là một phản hồi quan trọng ở hai cấp độ:

  • thiết kế cụ thể của bạn cần phải thích nghi với thế giới đang thay đổi, và
  • quy trình thiết kế của bạn cần được điều chỉnh để phù hợp với các khả năng như vậy trong tương lai (tức là lần sau hãy suy nghĩ thông qua trường hợp sử dụng đọc và viết cho thiết bị trước tốt hơn).

2

Nó luôn luôn quan trọng khi bạn tạo bất kỳ tài liệu nào để hiểu mục đích của nó là gì.

Tôi nghĩ rằng chúng ta phải cẩn thận những gì chúng ta gọi là tài liệu "kiến trúc". Tất cả chỉ là vấn đề phạm vi.

Nếu bạn đang nói về một hệ thống yêu cầu một số nhóm hoặc nhóm nhóm, thì bạn đang nói về một tài liệu mà mục đích của họ là để chi tiết hóa ở mức tối thiểu:

  • Các thành phần trong hệ thống là gì
  • Các thành phần được kết nối như thế nào
  • Trách nhiệm của từng thành phần là gì
  • Ai nên làm việc trên từng thành phần

Nếu tài liệu của bạn dành cho một hệ thống nhỏ hơn thì bạn có thể giảm số lượng mục bạn cần đưa vào vì một số giả định sẽ vốn có cho hệ thống hiện tại. Ví dụ: giả sử bạn kết hợp một tính năng cần thực hiện trong một trang web và một số cuộc gọi mới trong API, thì tài liệu của bạn sẽ phục vụ như một cách để hiểu rõ hơn:

  • Logic gì sẽ sống trong trang web
  • Logic nào sẽ sống trong API
  • API sẽ gọi các hợp đồng là gì (đoán đúng nhất)

Các tài liệu phác thảo này phục vụ để đưa các cuộc hội thoại lên phía trước về việc ai nên làm gì và nên tích hợp chúng như thế nào. Một khi những quyết định đó được đưa ra thì các đội có thể vận hành phần lớn tự chủ với cơ hội các vấn đề hội nhập thấp hơn nhiều.

Các vấn đề tích hợp bạn nhận thấy càng nhiều, tài liệu bạn nên càng chi tiết.


1

Bạn dường như đã vấp phải một câu hỏi hóc búa phổ biến trong Phát triển phần mềm. Không thể lập kế hoạch cho toàn bộ hệ thống trước khi bạn bắt đầu xây dựng nó, bởi vì có quá nhiều điều bạn chưa biết.

Đây là lý do tại sao các phương pháp Agile sử dụng phát triển lặp, bởi vì nó cho phép phản hồi thường xuyên thay đổi hướng của phần mềm, thay vì để mọi thứ tiến xa hơn từ những gì thực sự cần thiết. Mỗi thay đổi sẽ ảnh hưởng đến thiết kế.

Vì vậy, đã nói tất cả những điều này, tôi thực sự đã viết hai phương thức cho kịch bản cụ thể mà bạn mô tả ở trên, nhưng tôi sẽ gói gọn logic được chia sẻ trong một phương thức riêng thứ ba có thể được sử dụng bởi hai phương thức. Theo cách này, các phương thức công khai chịu trách nhiệm cho một điều duy nhất và dễ đặt tên, read_filewrite_filenói chính xác những gì chúng làm, trong khi đó do_filelà mơ hồ.

Những cuốn sách như Clean Code , Robert C Martin và Recentent Design , Scott L Bain sẽ cung cấp cho bạn những hiểu biết chi tiết hơn về chủ đề này.


1

Đây có thể chỉ là kết quả của sự thiếu kinh nghiệm của tôi khi thiết kế, nhưng mặt khác, chúng tôi có những phương pháp nhanh nhẹn nói rằng "chúng tôi từ bỏ kế hoạch từ xa, mọi thứ sẽ thay đổi trong vài ngày nữa", thường là vậy tôi cảm thấy thế nào

Không thể lập kế hoạch trước từng chi tiết. Hoàn toàn chấp nhận được để thay đổi ở đây và ở đó.

Tuy nhiên, điều quan trọng là lập kế hoạch trước. Làm nhanh không có nghĩa là không có thiết kế và không có kế hoạch gì cả , nhưng điều đó có nghĩa là bạn đang mong đợi những thay đổi.

Vì vậy, chính xác tôi nên "sử dụng" thiết kế như thế nào?

Bạn nên sử dụng thiết kế của bạn như nó là. Vì nó không được viết trong đá, nên rất dễ để thay đổi nó.


1

Lượng thời gian bạn dành cho kiến ​​trúc nên được xác định theo mức độ rủi ro trong phần đó của hệ thống.

Nói chung, bạn sẽ muốn đưa ra quyết định khá sớm về (các) kiểu kiến ​​trúc - lớp, thành phần, pub-sub, v.v., không có số lượng mã sạch và khớp nối lỏng lẻo sẽ giúp bạn dễ dàng chuyển đổi kiểu vào cuối một dự án.

Làm điều đó sẽ cho bạn một ý tưởng cơ bản về các khối xây dựng khác nhau trong hệ thống của bạn và lộ trình sẽ như thế nào khi hệ thống và các yêu cầu của bạn phát triển theo thời gian.

Khi bạn đã sử dụng các trường hợp sử dụng, tôi tin rằng bạn nên thiết kế đủ để đảm bảo bạn hiểu vấn đề và giải pháp đầy đủ. Nếu đó là mã nồi hơi mà bạn đã làm đi làm lại thì nguy cơ bị sai (theo nghĩa kiến ​​trúc - dĩ nhiên bạn vẫn cần kiểm tra) là khá thấp và do đó, số lượng thiết kế phía trước có khả năng được khá tối thiểu. Nếu đó là một vấn đề mới, hoặc một vấn đề với một giải pháp không rõ ràng hoặc một vấn đề tiềm ẩn rủi ro cho doanh nghiệp thì nó sẽ xứng đáng với nhiều thời gian hơn để suy nghĩ mọi thứ.

Tất nhiên có rất nhiều cách để làm điều này - UML, nguyên mẫu, phác thảo bảng trắng, v.v. Dù bạn sử dụng phương pháp nào - điều quan trọng là phải nhớ rằng mục đích của chúng là giúp bạn suy nghĩ và truyền đạt về thiết kế của bạn.

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.