Thiết kế cho những thay đổi trong tương lai hoặc giải quyết vấn đề trong tầm tay [đóng]


37

Trong khi viết mã hoặc trong quá trình thiết kế, bạn cố gắng khái quát hóa vấn đề ngay từ lần đầu tiên hoặc cố gắng giải quyết vấn đề rất cụ thể đó.

Tôi đang hỏi điều này bởi vì cố gắng khái quát hóa vấn đề có xu hướng làm phức tạp mọi thứ (có thể không cần thiết) và mặt khác, sẽ rất khó để mở rộng giải pháp cụ thể nếu có thay đổi trong yêu cầu.

Tôi đoán giải pháp là tìm đường giữa dễ nói hơn làm. Làm thế nào để bạn giải quyết loại vấn đề này? Nếu bạn bắt đầu khái quát nó vào thời điểm nào bạn biết rằng phần lớn khái quát này là đủ?



Điều này đặt ra một câu hỏi rất quan trọng: bạn có thể thực sự dự đoán các yêu cầu sẽ thay đổi như thế nào không?
dùng16764

Rất nhiều người sẽ cho bạn biết YAGNI. Đó là những người bạn coi thường khi bạn phải tiếp quản công việc của họ.
Martin Maat

Câu trả lời:


60

Quá thường xuyên khi bạn cố gắng thiết kế cho tương lai, dự đoán của bạn về nhu cầu trong tương lai hóa ra là sai. Việc tái cấu trúc thường tốt hơn khi bạn thực sự biết nhu cầu đã thay đổi như thế nào hơn là thiết kế lại hệ thống của bạn vào ngày đầu tiên. Đồng thời, đừng tự bắn vào chân mình. Chắc chắn có một nền tảng trung gian, và biết nơi đó là nghệ thuật hơn khoa học.

Để đun sôi nó xuống theo một quy tắc của ngón tay cái: ít hơn là nhiều hơn.


17
+1 "Tương lai không như trước đây."
Dan Lyons

19

Bạn có quen thuộc với Agile không? Một trong những nguyên tắc lớn của Agile là YAGNI . Tôi thấy đó là cách tốt nhất để tiếp cận mọi thứ.

"Bạn sẽ không cần nó" ... là một nguyên tắc lập trình cực đoan (XP) nói rằng lập trình viên không nên thêm chức năng cho đến khi thấy cần thiết. Ron Jeffries viết: "Luôn thực hiện mọi thứ khi bạn thực sự cần chúng, không bao giờ khi bạn thấy trước rằng bạn cần chúng."

... YAGNI là một nguyên tắc đằng sau thực tiễn XP về "làm điều đơn giản nhất có thể có thể làm việc" (DTSTTCPW). Nó có nghĩa là được sử dụng kết hợp với một số thực tiễn khác, chẳng hạn như tái cấu trúc liên tục, thử nghiệm đơn vị tự động liên tụctích hợp liên tục . Được sử dụng mà không tái cấu trúc liên tục, nó có thể dẫn đến mã lộn xộn và làm lại lớn. Tái cấu trúc liên tục lần lượt dựa vào các thử nghiệm đơn vị tự động như một mạng lưới an toàn (để phát hiện các lỗi không lường trước được) và tích hợp liên tục để ngăn chặn các vấn đề tích hợp rộng hơn ...

YAGNI không được chấp nhận phổ biến như một nguyên tắc hợp lệ, thậm chí kết hợp với các thực tiễn hỗ trợ. Nhu cầu kết hợp nó với các thực tiễn hỗ trợ, thay vì sử dụng độc lập, là một phần của định nghĩa ban đầu về XP ...


3
Mặc dù tôi đồng ý với YAGNI ít nhiều, tôi không thể tìm thấy nó trong các nguyên tắc nhanh: agilemanifesto.org/principles.html
Jens Schauder

"Đơn giản - nghệ thuật tối đa hóa số lượng công việc không được thực hiện - là điều cần thiết", sẽ áp dụng cho YAGNI và một số thực hành nhanh nhẹn khác.
tvanfosson

1
Mặc dù nó không đặc biệt nói "YAGNI" trong bản tuyên ngôn, tôi nghĩ rằng chúng rất phù hợp với nhau.

2
@Jens và @Matt, YAGNI, ở Agile bằng cách XP được đóng gói như một phương pháp "nhanh nhẹn". Như đã đề cập trong bài viết trên Wikipedia, nguyên tắc YAGNI được Ron Jeffries phát triển như một phần của các hoạt động cốt lõi của XP.

1
Có thể đúng là YAGNI là thành ngữ của nhà phát triển, nhưng TDD là người áp dụng tình huống khó xử này khá độc đáo. Trong bước mà nó nói rằng bạn chỉ nên viết đủ mã để vượt qua bài kiểm tra và không hơn thế nữa. Và TDD là một phần của nhanh nhẹn.
Robert Koritnik

12

Đây có lẽ là một trong những phần khó nhất trong phát triển phần mềm bởi vì bạn cần phải đi qua ranh giới giữa "YAGNI" và "PYIAC" (Vẽ chính mình vào một góc).

Thật dễ dàng để nói "không viết một tính năng trừ khi bạn cần nó". Phần khó là thiết kế mã của bạn để bạn có thể dễ dàng thêm các tính năng sau này khi bạn cần chúng.

Điều quan trọng là có thể thiết kế một kiến ​​trúc có thể mở rộng, nơi bạn không viết bất kỳ mã nào nhiều hơn những gì bạn hiện cần. Khả năng làm tốt điều này thực sự đến từ rất nhiều kinh nghiệm (và nỗi đau).


7

Tôi dành một chút thời gian để suy nghĩ về hướng chung của thiết kế - không quá nhiều, nhưng đủ để cơ bản phác thảo ra một cái nhìn tổng quan cấp cao. Sau đó tôi theo một phương pháp nhanh nhẹn dựa trên câu chuyện bằng cách sử dụng TDD để phát triển các giải pháp cho các câu chuyện riêng lẻ. Khi tôi triển khai qua TDD, tôi luôn ghi nhớ tổng quan cấp cao của mình và (a) chỉ đạo các triển khai cụ thể của tôi tuân theo tổng quan cấp cao hoặc (b) tái cấu trúc (và cải thiện) sự hiểu biết / định hướng cấp cao của tôi dựa trên những gì tôi học được trong quá trình thử nghiệm / thực hiện.

Tôi nghĩ rằng đó là một sai lầm khi không lên kế hoạch trả trước, nhưng có lẽ đó là một lỗi lớn hơn để làm quá nhiều. Càng nhiều càng tốt, tôi muốn để tôi trải nghiệm hướng dẫn tôi trong bức tranh lớn và sau đó để thiết kế phát triển một cách hữu cơ theo các dòng tôi đã đặt ra trong đầu về cách ứng dụng sẽ phát triển. Sử dụng TDD tôi thấy rằng bản thân thiết kế bị ép buộc vào các nguyên tắc thiết kế tốt hơn (tách rời, chịu trách nhiệm duy nhất, v.v.) và dễ uốn nắn hơn đối với các thay đổi so với khi tôi cố gắng hình thành toàn bộ và phù hợp với sự phát triển của nó.


3

Một thiết kế tốt chứa đựng những thay đổi trong tương lai và chắc chắn là đáng để đi. Hãy xem xét hệ điều hành UNIX và "mọi thứ là một triết lý tập tin". Quyết định thiết kế đó được đưa ra không phải để đáp ứng một số nhu cầu trước mắt mà là để đáp ứng các yêu cầu trong tương lai. Người ta rùng mình khi nghĩ hệ điều hành dựa trên thiết kế "nhanh nhẹn" sẽ trông như thế nào.


2

Những gì bạn đang cố gắng giải quyết phải làm với việc tái sử dụng (nghĩa là khái quát hóa một vấn đề mà bạn đang giải quyết để bạn có thể sử dụng lại công việc (mã) trong tương lai). Tôi đã nói điều đó trước đây và tôi sẽ liên kết lại.

Tôi nghĩ rằng tôi đã nghe người khác nói điều gì đó về tác dụng của:

Tôi giải quyết vấn đề lần đầu tiên. Khi tôi lặp lại giải pháp của mình lần đầu tiên, tôi lưu ý nó. Khi tôi lặp lại một lần nữa, tôi tái cấu trúc.


2

Thiết kế cho "bây giờ + 1". Điều đó có nghĩa là, giải quyết vấn đề tức thời và xây dựng đủ chức năng để lần sau họ yêu cầu thay đổi, bạn đã hoàn thành được một nửa (hoặc hơn) và có thể chọn một) giải quyết ngay lập tức và tái cấu trúc lại sau hoặc b) giải quyết "now + 1" lần nữa (với nửa "bây giờ" đã hoàn thành)

Điều này không phụ thuộc vào dự án và, nói tóm lại, kinh nghiệm sẽ cho bạn biết "+1" là gì.


1

Triết lý của YAGNI , You Ain't Gonna Need It, có thể được tóm tắt với (từ bài viết):

Theo những người ủng hộ cách tiếp cận YAGNI, sự cám dỗ để viết mã không cần thiết vào lúc này, nhưng có thể trong tương lai, có những nhược điểm sau:

  • Thời gian sử dụng được lấy từ việc thêm, kiểm tra hoặc cải thiện chức năng cần thiết.
  • Các tính năng mới phải được gỡ lỗi, ghi lại và hỗ trợ.
  • Bất kỳ tính năng mới nào cũng áp đặt các ràng buộc đối với những gì có thể được thực hiện trong tương lai, do đó, một tính năng không cần thiết bây giờ có thể ngăn việc triển khai một tính năng cần thiết sau này.
  • Cho đến khi tính năng này thực sự cần thiết, thật khó để xác định đầy đủ những gì nó nên làm và kiểm tra nó. Nếu tính năng mới không được xác định và kiểm tra đúng cách, nó có thể không hoạt động đúng, ngay cả khi cuối cùng là cần thiết.
  • Nó dẫn đến sự phình to mã; phần mềm trở nên lớn hơn và phức tạp hơn.
  • Trừ khi có thông số kỹ thuật và một số loại kiểm soát sửa đổi, tính năng này có thể không được biết đến đối với các lập trình viên có thể sử dụng nó.
  • Thêm tính năng mới có thể đề xuất các tính năng mới khác. Nếu các tính năng mới này cũng được triển khai, điều này có thể dẫn đến hiệu ứng quả cầu tuyết đối với chủ nghĩa kỳ công leo.

0

Tôi là một tín đồ lớn của việc thiết kế cho vấn đề trong tay và không thổi phồng thiết kế của bạn bằng cách cố gắng đoán tất cả các trường hợp mà bạn phải phục vụ vì "một ngày nào đó chúng ta có thể cần nó".

Về cơ bản, đưa ra một danh sách các yêu cầu cụ thể, thiết kế theo đó, tuy nhiên, điều này không có nghĩa là bạn không nên:

  • làm cho các khía cạnh của thiết kế của bạn có thể cấu hình thay vì mã hóa cứng các khía cạnh đó trong giải pháp của bạn. Thông qua các tham số được truyền trong thời gian chạy hoặc thông qua cấu hình bên ngoài được đọc khi khởi động (hoặc sau khi HUP'ing).
  • thắt mã của bạn với số ma thuật,
  • tránh nhìn vào nếu có một cái gì đó đã được viết mà bạn có thể sử dụng lại, có thể sau khi điều chỉnh giải pháp hiện có để đưa ra một cách tiếp cận phù hợp với tình huống hiện tại cũng như cho (các) yêu cầu mới.

Vấn đề chính với việc thiết kế cho "tương lai có thể" là bạn luôn chỉ đoán. Có thể đưa ra những phỏng đoán có giáo dục, nhưng "khi bị xô đẩy" thì đó vẫn chỉ là một loạt những phỏng đoán.

Bằng cách này, bạn cũng có khả năng thực sự siết chặt giải pháp của mình để phù hợp với (các) trường hợp chung thay vì giải quyết vấn đề cụ thể trong tay như được xác định bởi (các) yêu cầu đã biết của bạn.

Nói gì vậy? "Khi tất cả những gì bạn có là một cái búa, mọi thứ bắt đầu trông giống như một cái đinh".

Tôi ước tôi có một pound cho mỗi lần tôi nghe ai đó nói, "Nhưng đó là một giải pháp thích nghi hơn cho những trường hợp chung mà chúng ta có thể thấy trong tương lai."

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.