Làm thế nào để bạn quản lý một bước nhảy phức tạp?


13

Có vẻ như một trải nghiệm không thường xuyên nhưng phổ biến là đôi khi bạn đang làm việc trong một dự án và đột nhiên một thứ gì đó bất ngờ xuất hiện, ném một cờ lê lớn vào công việc và làm tăng sự phức tạp lên rất nhiều.

Ví dụ, tôi đang làm việc trên một ứng dụng nói chuyện với các dịch vụ SOAP trên nhiều máy khác. Tôi đã tạo ra một nguyên mẫu hoạt động tốt, sau đó tiếp tục phát triển một mặt trước thông thường và nói chung mọi thứ đều hoạt động tốt, khá đơn giản và dễ theo dõi. Nó hoạt động rất tốt cho đến khi chúng tôi bắt đầu thử nghiệm trên một mạng rộng hơn và đột nhiên các trang bắt đầu hết thời gian do độ trễ của các kết nối và thời gian cần thiết để thực hiện tính toán trên các máy từ xa dẫn đến yêu cầu hết thời gian cho các dịch vụ xà phòng. Hóa ra chúng ta cần thay đổi kiến ​​trúc để quay các yêu cầu lên các luồng của riêng họ và lưu trữ dữ liệu được trả về để có thể cập nhật dần dần trong nền thay vì thực hiện các phép tính theo yêu cầu.

Các chi tiết của kịch bản đó không quá quan trọng - thực sự đó không phải là một ví dụ tuyệt vời vì nó khá khó hiểu và những người đã viết rất nhiều ứng dụng loại này cho loại môi trường này có thể đã dự đoán được - ngoại trừ việc nó minh họa một cách mà người ta có thể bắt đầu với một tiền đề và mô hình đơn giản và đột nhiên có sự leo thang phức tạp cũng vào sự phát triển của dự án.

Những chiến lược nào bạn có để đối phó với các loại thay đổi chức năng này có nhu cầu phát sinh - thường là kết quả của các yếu tố môi trường thay vì thay đổi đặc điểm kỹ thuật - sau này trong quá trình phát triển hoặc kết quả của thử nghiệm? Làm thế nào để bạn cân bằng giữa việc tránh tối ưu hóa sớm / YAGNI / khắc phục rủi ro khi thiết kế một giải pháp giảm thiểu các vấn đề có thể nhưng không nhất thiết có thể xảy ra, trái với việc phát triển một giải pháp đơn giản và dễ dàng hơn có hiệu quả nhưng không kết hợp sẵn sàng cho mọi tình huống có thể xảy ra?

Chỉnh sửa: Câu trả lời của Crazy Eddie bao gồm "bạn hút nó và tìm cách ít tốn kém nhất để thực hiện sự phức tạp mới." Điều đó khiến tôi nghĩ về điều gì đó tiềm ẩn trong câu hỏi nhưng tôi không nêu ra cụ thể.

Một khi bạn đạt được vết sưng đó, và bạn kết hợp những thay đổi cần thiết. Bạn có làm điều đó sẽ giữ dự án gần với tiến độ nhất có thể nhưng có thể ảnh hưởng đến khả năng bảo trì hoặc bạn quay lại kiến ​​trúc của mình và làm lại ở mức chi tiết hơn có thể duy trì hơn nhưng sẽ đẩy mọi thứ trở lại trong quá trình phát triển?

Câu trả lời:


8

Điều tôi nghĩ đến khi đọc điều này là câu ngạn ngữ nhanh nhẹn: giải quyết các nhiệm vụ rủi ro nhất và / hoặc ít được hiểu rõ nhất trước tiên trong vòng đời dự án . Tức là cố gắng kết hợp một bộ xương làm việc của dự án càng sớm càng tốt, để chứng minh rằng khái niệm này hoạt động. Điều này cũng cho phép người ta thực hiện bất kỳ loại thử nghiệm tàn khốc nào để phát hiện xem kiến ​​trúc có thực sự mang lại lời hứa trong hoàn cảnh thực tế hay không. Ngoài ra, nếu có bất kỳ công nghệ / nền tảng / công cụ mới, chưa biết nào được đưa vào giải pháp, hãy sử dụng sớm trên đĩa.

Nếu kiến ​​trúc cốt lõi là OK, các chức năng riêng lẻ có thể được thêm và kiểm tra tăng dần, và được tái cấu trúc khi cần thiết, với chi phí tương đối ít hơn. Cần thay đổi kiến ​​trúc là rủi ro lớn, mà người ta phải đối phó với trả trước. Điều này mang lại phản hồi nhanh chóng: trong trường hợp xấu nhất, nếu toàn bộ khái niệm sụp đổ, chúng tôi biết điều đó sớm và có thể hủy bỏ dự án với tổn thất tối thiểu.


6

Ví dụ của bạn đã chạm vào một số khía cạnh thách thức nhất của lập trình, cụ thể là điện toán phân tánlập trình đồng thời , đang trở nên được sử dụng rộng rãi hơn và khiến các lập trình viên làm việc trở nên khó khăn hơn bao giờ hết.

Ngay cả lập trình "bình thường" (một luồng trên một máy) rất phức tạp đối với bất kỳ chương trình không có giá trị nào, đến nỗi cần có kỹ năng tuyệt vời và nhiều năm kinh nghiệm để có được bất kỳ điều gì tốt - nhưng vẫn còn xa "giải quyết". Ngay cả ở mức độ phức tạp này, chủ yếu là do vụ nổ tổ hợp , vượt xa khả năng của bộ não con người để hoàn toàn nắm bắt và hiểu được. Nghĩ khác là ngu.

Điện toán phân tán và lập trình đồng thời thêm hai chiều nữa vào kích thước của không gian "phức tạp", tăng ít nhất là theo khối (sp?) (N ^ 3) so với lập trình "bình thường". Ví dụ, hãy nghĩ về một số vấn đề và sai lầm mới mà chúng ta phải đối phó. Thậm chí để chơi với một ý tưởng, rằng bạn có thể hiểu được các mối liên kết và tác dụng phụ ở quy mô này là đáng cười.

Tôi rõ ràng không có viên đạn bạc nào, nhưng tôi khá chắc chắn rằng sai lầm lớn nhất mà người ta có thể mắc phải là nghĩ rằng bạn hiểu tất cả & giải quyết nó.

Một số ý tưởng về cách đối phó với tất cả những điều này, ngoài những câu trả lời khác đã được đề cập:

  • Khiêm tốn
  • Chấp nhận rằng hệ thống / chương trình của bạn là không hoàn hảo, vô thường và không đầy đủ .
  • Chuẩn bị cho lỗi
  • Nắm lấy thay đổi
  • Kế hoạch dự phòng
  • Hãy suy nghĩ về việc chứng minh trong tương lai
  • Nhìn vào (hoặc nghiên cứu) sinh học hoặc xã hội học cách các hệ thống phức tạp hành xử
  • Cố gắng hết sức để tránh trạng thái đột biến. Sử dụng các giao thức không trạng thái (như REST và HTTP).
  • Lập trình chức năng có thể làm giảm bớt một số nỗi đau

Tôi đoán tôi có thể đi và về. Môn học rất thú vị :)


Nhìn vào (hoặc nghiên cứu) sinh học hoặc xã hội học về cách các hệ thống phức tạp hoạt động - C'mon. Phần còn lại của câu trả lời của bạn là vững chắc, nhưng điều này có một ứng dụng ngoại vi cho vấn đề được mô tả.
Jim G.

1
@Jim G. Có thể. Sinh học sẽ không giúp tối ưu hóa các vòng lặp của bạn, nhưng nếu bạn muốn đưa ra những quan điểm mới, hiểu biết sâu sắc hoặc trừu tượng hiệu quả (về phát triển phần mềm), điều đó sẽ giúp bước ra khỏi hộp cát của một người. Lập luận rằng sinh học (hay xã hội học) không liên quan gì đến lập trình, nó chỉ cách vài bước để tranh luận rằng OOP hoặc các mẫu thiết kế không liên quan gì đến lập trình. Ví dụ: OOP : sinh học -> Alan Kay -> OOP / Smalltalk. Hoặc các mẫu thiết kế : xã hội học -> thiết kế đô thị -> Christopher Alexander -> Ngôn ngữ mẫu -> Mẫu thiết kế.
Maglob

@Jim G. Tiếp. Một số trích dẫn, Alan Kay: "Tôi nghĩ rằng các vật thể giống như tế bào sinh học và / hoặc máy tính cá nhân trên mạng, chỉ có thể giao tiếp với tin nhắn" và Wikipedia: "[Mẫu thiết kế] Ý tưởng được kiến ​​trúc sư Christopher Alexander đưa ra trong lĩnh vực kiến ​​trúc [1] và đã được điều chỉnh cho nhiều ngành khác nhau, bao gồm cả khoa học máy tính "
Maglob

Ổn thỏa. Tôi sẽ cho bạn +1 cho Hãy cố gắng hết sức để tránh trạng thái có thể thay đổi và các loại cốm khác. Quan điểm của tôi là nếu người quản lý của bạn giao nhiệm vụ cho bạn giảm bớt sự phức tạp, chắc chắn bạn sẽ áp dụng dao cạo của Occam cho vấn đề và bắt tay vào việc. Tôi không nghĩ rằng bạn hoặc bất kỳ ai khác sẽ "tìm đến sinh học" để được giúp đỡ với vấn đề trước mắt.
Jim G.

2

Tôi không đồng ý với tinh thần của câu trả lời của @ Péter Török vì cho rằng một nhóm (hoặc cá nhân) có thể nhất thiết phải thấy trước các mục rủi ro nhất trong vòng đời dự án. Chẳng hạn, trong trường hợp của OP, nhóm nghiên cứu không thể thấy trước sự phức tạp leo thang gắn liền với giải pháp đa luồng cho đến khi lưng họ dựa vào tường.

Câu hỏi của OP là một câu hỏi hay và nó nói lên một vấn đề mà nhiều cửa hàng phát triển phần mềm gặp phải.

Đây là cách tôi sẽ giải quyết vấn đề:

  1. Làm theo lời khuyên của Fred Brooks và tổ chức các nhà phát triển của bạn như một nhóm phẫu thuật .
  2. Chọn một bác sĩ phẫu thuật bậc thầy khôn ngoan và "nhân từ" có thể vừa: A) Tạo được sự tin tưởng và tôn trọng của bạn bè; và B) Đưa ra quyết định khó khăn một cách kịp thời.
  3. Mong các bác sĩ phẫu thuật bậc thầy sẽ giảm bớt sự phức tạp ở phần đầu và phần cuối của quá trình phát triển.

Thêm về điểm số 3:

  1. Bác sĩ phẫu thuật bậc thầy nên thực hiện một nỗ lực có ý thức để đề xuất giải pháp đơn giản nhất sẽ có hiệu quả. Nhiều năm kinh nghiệm có ý nghĩa nên đặt bác sĩ phẫu thuật bậc thầy vào một vị trí để làm như vậy.
  2. Tổ chức rộng hơn, đó là cấp trên của bác sĩ phẫu thuật, sẽ cung cấp cho nhóm đủ thời gian và nguồn lực để giảm độ phức tạp sau ngày tàu. Điều này sẽ cho phép nhóm phát triển cả hai mã tàu kịp thời và thực hiện kaizen để giảm độ phức tạp trong một cơ sở liên tục.

IMHO trong trường hợp của OP, lẽ ra họ nên bắt đầu thử nghiệm sớm hơn, để khám phá cách (và nếu) kiến ​​trúc của họ hoạt động trong hoàn cảnh thực tế. Btw bằng cách gợi ý để có một "bậc thầy bác sĩ phẫu thuật", bạn dường như ngụ ý rằng về cơ bản có được những người có thể lường trước được những rủi ro kỹ thuật của dự án - điểm chính xác mà bạn khẳng định không đồng ý với.
Péter Török

@ Péter Török: ... Bằng cách đề nghị có một "bác sĩ phẫu thuật bậc thầy", về cơ bản, bạn dường như ngụ ý rằng có những người có thể thấy trước những rủi ro kỹ thuật của dự án : Không, tôi không. Tôi đang nói rằng những người này là cả hai: A) Phù hợp nhất để hoàn toàn tránh sự phức tạp ngay từ đầu; và B) Thích hợp nhất để đào một đội khỏi sự phức tạp sau khi mã được chuyển đi.
Jim G.

IMHO chúng ta đang nói về điều tương tự. Kinh nghiệm giúp "bác sĩ phẫu thuật bậc thầy" của bạn chọn giải pháp đơn giản nhất có thể làm việc được xây dựng từ những ký ức về các dự án và giải pháp trong quá khứ và biết giải pháp nào hoạt động (hoặc không) trong trường hợp cụ thể nào. Nói cách khác, anh ấy xem qua các giải pháp áp dụng cho một vấn đề cụ thể và đánh giá lợi ích và rủi ro tiềm ẩn của mỗi vấn đề. Đây là những gì giúp anh ấy / cô ấy chọn đúng cho tình huống hiện tại, do đó tránh được những con đường rủi ro hơn .
Péter Török

1
Điều này làm tôi nhớ đến một câu trích dẫn từ người huấn luyện ngựa quá cố, tuyệt vời Ray Hunt: "Làm thế nào để bạn có được sự phán đoán tốt? Kinh nghiệm. Làm thế nào để bạn có được kinh nghiệm? Đánh giá tồi tệ."
glenatron

1

Mã cho giao diện

Khi viết chức năng mới giao thoa với chức năng khác, hãy tạo một ranh giới dưới dạng giao diện (loại Java) mà tất cả đều vượt qua. Điều này sẽ

  1. đảm bảo bạn có toàn quyền kiểm soát những chức năng được sử dụng
  2. cho phép bạn có nhiều triển khai cùng chức năng.
  3. giảm độ phức tạp tổng thể xuống vì các mô-đun chỉ được kết nối mỏng thay vì được đan xen hoàn toàn.

0

người ta có thể bắt đầu với một tiền đề và mô hình đơn giản và đột nhiên có sự leo thang phức tạp cũng vào sự phát triển của dự án

Không đáng ngạc nhiên.

Đây là sự phát triển phần mềm. Nếu bạn không phát minh ra thứ gì mới, bạn đang tải xuống một giải pháp đã được chứng minh.

Có ít đất ở giữa.

Nếu bạn đang phát minh ra một cái gì đó mới, thì phải có ít nhất một tính năng bạn không hiểu đầy đủ. (Để hiểu đầy đủ về nó, bạn phải có một triển khai hoạt động mà bạn sẽ sử dụng.)

Làm thế nào để quản lý điều này?

  1. Có kỳ vọng thực tế. Bạn đang phát minh ra một cái gì đó mới. Có phải là những phần bạn không hiểu.

  2. Có kỳ vọng thực tế. Nếu nó có vẻ hoạt động ngay lần đầu tiên, bạn đã bỏ qua điều gì đó.

  3. Có kỳ vọng thực tế. Nếu nó đơn giản, người khác sẽ thực hiện nó trước, và bạn có thể chỉ cần tải xuống giải pháp đó.

  4. Có kỳ vọng thực tế. Bạn không thể dự đoán tương lai rất tốt.


2
Đợi đã, vậy điều bạn đang nói là: Có kỳ vọng thực tế không?
glenatron

0

Thiết kế và mã với lỗi thời trong tâm trí. Giả sử rằng những gì bạn mã ngày hôm nay sẽ cần phải được cắt bỏ và thay thế vào ngày mai.


0

Môi trường nên là một phần của đặc điểm kỹ thuật. Do đó, một sự thay đổi đối với môi trường là một sự thay đổi về đặc điểm kỹ thuật. Mặt khác, nếu bạn dựa trên nguyên mẫu và thiết kế của mình trên một môi trường khác với những gì có trong thông số kỹ thuật, bạn đã phạm một sai lầm ngu ngốc. Dù bằng cách nào, bạn hút nó lên và tìm ra cách ít tốn kém nhất để thực hiện sự phức tạp mới.


0

Như với hầu hết các vấn đề lập trình, nó phụ thuộc , theo ý kiến của tôi. Vấn đề này thực chất đối với công việc sáng tạo, đến nỗi bạn không nên quên rằng những thất bại sẽ xảy ra, và điều đó ổn . Lập trình là một vấn đề tồi tệ và bạn thường không biết giải pháp đúng cho vấn đề cho đến khi bạn đã giải quyết xong.

Tuy nhiên, có một loạt các yếu tố địa phương, cụ thể có thể xuất hiện ở đây, chẳng hạn như:

  • Các mục tiêu cho hệ thống này. Có phải là một điều một lần? Bạn có định giữ cho hệ thống này hoạt động trong trung hạn đến dài hạn không?

Đối với những thứ ngắn hạn, có thể không đáng để suy nghĩ về nó quá đủ để chỉ cho nó chạy. Tái cấu trúc rất tốn kém và đó là thứ không tạo ra giá trị cuối cùng ngay lập tức cho người dùng của bạn. Tuy nhiên, gần như không có trường hợp nào tôi có thể nghĩ đến ngoài phần mềm vứt bỏ tuyệt đối, trong đó ngắn hạn đến mức không đáng để cải thiện thiết kế của bạn. Điều quan trọng hơn nhiều là có thể hiểu những gì bạn đã làm và khắc phục nó nhanh hơn là hoàn thành ngay bây giờ. Nếu đó là về lâu dài, thì cuối cùng nó sẽ có khả năng thanh toán (và có thể sớm hơn nhiều so với mọi người nghĩ), hoặc ngược lại (không làm điều đó sẽ gây ra nỗi đau rất sớm thay vì "khi chúng ta phải sửa chữa nó"). Tôi gần như bị cám dỗ để nói "luôn luôn dành thời gian để làm cho nó tốt hơn", nhưng có một số trường hợp không thể.

  • Những mục tiêu của đội. Là nhiều hơn một loại "làm ngay bây giờ, bằng bất cứ giá nào", hoặc một loại "hãy làm đúng"?

Điều này sẽ ảnh hưởng đến quyết định của bạn rất lớn. Nhóm của bạn sẽ hỗ trợ quyết định này bằng cách cung cấp cho bạn các tài nguyên để thiết kế lại hoặc họ sẽ yêu cầu giải pháp nhanh chóng được thực hiện ngay bây giờ. Theo tôi, nếu bạn thấy rằng đội đang đẩy bạn đi sai hướng một cách nhất quán, thì đó là một lá cờ đỏ khổng lồ. Tôi đã thấy điều này xảy ra trong một kịch bản xảy ra tình trạng dập lửa liên tục, trong đó không bao giờ có thời gian để thiết kế lại vì bạn luôn khắc phục các sự cố mà thiết kế xấu của bạn tạo ra. Hiện tại cũng có thể có một nền tảng ở giữa: "ống băng", sửa ASAP (nhưng thực sự làm điều đó).

  • Sự hiểu biết của bạn về vấn đề. Tại sao giải pháp trước không hoạt động?

Thực sự quan trọng. Hãy suy nghĩ về lỗi hoặc vấn đề là gì và tại sao nó lại xảy ra. Loại tình huống này là một cơ hội tuyệt vời để tìm ra các giả định, hoặc thiếu) thiếu sót (hoặc thiếu). Nói chung, luôn ưu tiên hiểu vấn đề của bạn tốt hơn thay vì giải quyết vấn đề hiện tại. Đây có lẽ là sự bảo vệ lớn nhất của bạn chống lại YAGNI / áp đảo. Nếu bạn hiểu rõ vấn đề của mình đủ, thì bạn sẽ giải quyết chứ không phải các vấn đề khác.

Cuối cùng, hãy cố gắng xây dựng mọi thứ đúng cách . Tôi không nói về những lỗi và vấn đề bạn gặp phải khi bạn hiểu thêm về vấn đề hoặc lỗi con người vốn có của bạn. Tôi không có nghĩa là "đừng phạm sai lầm và làm cho nó hoàn hảo ngay lần đầu tiên" - điều đó là không thể. Ý tôi là, hãy cố gắng quản lý sự phức tạp tốt trong công việc hàng ngày của bạn, sửa chữa các cửa sổ bị hỏng, giữ cho nó đơn giản nhất có thể, cải thiện mã và suy nghĩ của bạn mọi lúc. Theo cách đó khi (không phải) thay đổi tiếng gõ cửa, bạn có thể chào đón nó với vòng tay rộng mở thay vì một khẩu súng ngắ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.