Việc theo RẮN có dẫn đến việc viết một khung trên đỉnh công nghệ không?


70

Tôi thích RẮN, và tôi cố gắng hết sức để sử dụng và áp dụng nó khi tôi đang phát triển. Nhưng tôi không thể không cảm thấy như thể cách tiếp cận RẮN biến mã của bạn thành mã 'khung' - tức là mã bạn sẽ thiết kế nếu bạn đang tạo khung hoặc thư viện cho các nhà phát triển khác sử dụng.

Nói chung, tôi đã thực hành 2 chế độ lập trình - tạo ra ít nhiều chính xác những gì được yêu cầu thông qua các yêu cầu và KISS (lập trình điển hình) hoặc tạo logic, dịch vụ rất chung chung và có thể tái sử dụng, cung cấp sự linh hoạt mà các nhà phát triển khác có thể cần (lập trình khung) .

Nếu người dùng thực sự chỉ muốn một ứng dụng thực hiện các thao tác x và y, thì việc theo dõi RẮN và thêm vào một loạt các điểm trừu tượng, khi bạn thậm chí không biết đó có phải là vấn đề hợp lệ hay không với? Nếu bạn thêm các điểm nhập cảnh trừu tượng này, bạn có thực sự đáp ứng các yêu cầu của người dùng hay bạn đang tạo một khung trên đầu trang của khung công nghệ và ngăn xếp hiện tại của bạn để giúp việc bổ sung trong tương lai dễ dàng hơn? Trong trường hợp nào bạn đang phục vụ lợi ích của khách hàng, hoặc của nhà phát triển?

Đây là điều có vẻ phổ biến trong thế giới Doanh nghiệp Java, nơi bạn cảm thấy như thể bạn đang thiết kế khung công tác của riêng bạn trên đầu J2EE hoặc Spring để nó là một UX tốt hơn cho nhà phát triển, thay vì tập trung vào UX cho người dùng?


12
Vấn đề với hầu hết các quy tắc lập trình ngắn của ngón tay cái là chúng có thể được giải thích, các trường hợp cạnh và đôi khi các định nghĩa của các từ trong các quy tắc đó không rõ ràng khi kiểm tra chặt chẽ hơn. Về cơ bản chúng có thể có nghĩa là rất nhiều thứ cho những người khác nhau. Có một số chủ nghĩa thực dụng phi ý thức hệ thường cho phép một người đưa ra quyết định khôn ngoan hơn.
Mark Rogers

1
Bạn làm cho nó nghe giống như tuân theo các nguyên tắc RẮN bằng cách nào đó ngụ ý một khoản đầu tư lớn, rất nhiều công việc phụ. Nó không, nó thực tế là miễn phí. Và nó có thể sẽ tiết kiệm cho bạn hoặc người khác một khoản đầu tư lớn trong tương lai vì nó giúp mã của bạn dễ dàng duy trì và mở rộng hơn. Bạn cứ hỏi những câu như "chúng ta nên làm bài tập về nhà hay làm cho khách hàng hài lòng?" Đây không phải là sự đánh đổi.
Martin Maat

1
@MartinMaat Tôi nghĩ rằng các hình thức RẮN cực đoan hơn bao hàm sự đầu tư lớn. I E. Phần mềm doanh nghiệp. Ngoài phần mềm doanh nghiệp, bạn sẽ có rất ít lý do để trừu tượng ORM, ngăn xếp công nghệ hoặc cơ sở dữ liệu của bạn bởi vì rất có khả năng bạn sẽ gắn bó với ngăn xếp đã chọn của mình. Theo nghĩa tương tự, bằng cách buộc bạn vào một khung, cơ sở dữ liệu hoặc ORM cụ thể, bạn đang phá vỡ các nguyên tắc RẮN vì bạn được ghép với ngăn xếp của mình. Mức độ linh hoạt từ RẮN là không bắt buộc ở hầu hết các công việc.
Igneous01


1
Biến hầu hết các mã thành một cái gì đó giống như một khung công tác không có vẻ khủng khiếp. Nó chỉ trở nên khủng khiếp nếu nó trở nên quá sức. Nhưng các khung có thể được tối thiểu và có ý kiến. Tôi không chắc liệu đây có phải là hậu quả không thể tránh khỏi khi theo RẮN hay không nhưng chắc chắn đó là hậu quả có thể xảy ra và tôi nghĩ bạn nên nắm lấy.
Konrad Rudolph

Câu trả lời:


84

Quan sát của bạn là chính xác, các nguyên tắc RẮN là IMHO được tạo ra với các thư viện có thể tái sử dụng hoặc mã khung. Khi bạn chỉ theo dõi tất cả chúng một cách mù quáng, mà không hỏi liệu nó có ý nghĩa hay không, bạn có nguy cơ tăng trưởng quá mức và đầu tư nhiều nỗ lực hơn vào hệ thống của bạn hơn có lẽ là cần thiết.

Đây là một sự đánh đổi, và nó cần một số kinh nghiệm để đưa ra quyết định đúng đắn về khi nào nên khái quát hóa và khi nào không. Một cách tiếp cận khả thi cho vấn đề này là tuân thủ nguyên tắc YAGNI - không làm cho mã của bạn RẮN "chỉ trong trường hợp" - hoặc, để sử dụng các từ của bạn: không

cung cấp sự linh hoạt mà các nhà phát triển khác có thể cần

thay vào đó, cung cấp sự linh hoạt mà các nhà phát triển khác thực sự cần ngay khi họ cần , nhưng không sớm hơn.

Vì vậy, bất cứ khi nào bạn có một hàm hoặc lớp trong mã của mình, bạn không chắc liệu nó có thể được sử dụng lại hay không, đừng đưa nó vào khung của bạn ngay bây giờ. Đợi cho đến khi bạn có một trường hợp thực tế để tái sử dụngtái cấu trúc để "RẮN đủ cho trường hợp đó". Không triển khai thêm cấu hình (theo OCP) hoặc các điểm nhập trừu tượng (sử dụng DIP) vào một lớp như bạn thực sự cần cho trường hợp tái sử dụng thực tế. Thêm sự linh hoạt tiếp theo khi yêu cầu tái sử dụng tiếp theo thực sự ở đó.

Tất nhiên, cách làm việc này sẽ luôn đòi hỏi một số lượng tái cấu trúc tại cơ sở mã làm việc hiện có. Đó là lý do tại sao các bài kiểm tra tự động rất quan trọng ở đây. Vì vậy, làm cho mã của bạn RẮN đủ ngay từ đầu để có thể kiểm tra đơn vị không phải là một sự lãng phí thời gian và làm như vậy không mâu thuẫn với YAGNI. Kiểm thử tự động là một trường hợp hợp lệ cho "tái sử dụng mã", vì mã liên quan được sử dụng từ mã sản xuất cũng như từ các thử nghiệm. Nhưng hãy nhớ, chỉ cần thêm sự linh hoạt mà bạn thực sự cần để làm cho các bài kiểm tra hoạt động, không hơn không kém.

Đây thực sự là trí tuệ cũ. Cách đây rất lâu trước khi thuật ngữ RẮN trở nên phổ biến, ai đó đã nói với tôi trước khi chúng ta thử viết lại mã có thể sử dụng được, chúng ta nên viết mã có thể sử dụng được . Và tôi vẫn nghĩ rằng đây là một khuyến nghị tốt.


23
Điểm tranh chấp thêm: Đợi cho đến khi bạn có 3 trường hợp sử dụng mà bạn thấy logic tương tự trước khi tái cấu trúc mã của bạn để sử dụng lại. Nếu bạn bắt đầu tái cấu trúc với 2 mảnh, thật dễ dàng để kết thúc trong tình huống thay đổi yêu cầu hoặc trường hợp sử dụng mới kết thúc phá vỡ sự trừu tượng mà bạn đã thực hiện. Ngoài ra, hãy giữ các bộ tái cấu trúc giới hạn ở những thứ có cùng trường hợp sử dụng: 2 thành phần có thể có cùng mã nhưng thực hiện những thứ hoàn toàn khác nhau và nếu bạn hợp nhất các thành phần đó, cuối cùng bạn sẽ liên kết logic đó, điều này có thể gây ra sự cố sau này.
Nzall

8
Tôi thường đồng ý với điều này, nhưng cảm thấy như nó quá tập trung vào các ứng dụng "một lần": Bạn viết mã, nó hoạt động tốt. Tuy nhiên, có rất nhiều ứng dụng có "hỗ trợ lâu dài". Bạn có thể viết một số mã và 2 năm sau, các yêu cầu nghiệp vụ thay đổi để bạn phải điều chỉnh mã. Vào thời điểm đó, rất nhiều mã khác có thể phụ thuộc vào nó - trong trường hợp đó, các nguyên tắc RẮN sẽ giúp thay đổi dễ dàng hơn.
R. Schmitz

3
"Trước khi chúng tôi cố gắng viết mã có thể sử dụng lại, chúng tôi nên viết mã có thể sử dụng được" - Rất khôn ngoan!
Graham

10
Có lẽ đáng lưu ý rằng việc chờ đợi cho đến khi bạn có trường hợp sử dụng thực tế sẽ giúp mã RẮN của bạn tốt hơn , bởi vì làm việc trong các giả thuyết là rất khó và bạn có thể đoán sai nhu cầu trong tương lai sẽ là gì. Dự án của chúng tôi có một số trường hợp mọi thứ được thiết kế để RẮN và linh hoạt cho các nhu cầu trong tương lai ... ngoại trừ nhu cầu trong tương lai hóa ra là những điều không ai nghĩ đến vào lúc đó, vì vậy cả hai chúng tôi cần tái cấu trúc có thêm sự linh hoạt vẫn không cần đến điều mà phải duy trì khi đối mặt với việc tái cấu trúc hoặc bị loại bỏ.
KRyan

2
Ngoài ra, thông thường bạn sẽ vẫn cần phải viết mã có thể kiểm tra, điều này thường có nghĩa là có một lớp trừu tượng đầu tiên để có thể chuyển từ triển khai cụ thể sang kiểm tra.
Walfrat

49

Từ kinh nghiệm của tôi, khi viết một ứng dụng, bạn có ba lựa chọn:

  1. Viết mã chỉ để đáp ứng các yêu cầu,
  2. Viết mã chung dự đoán các yêu cầu trong tương lai, cũng như đáp ứng các yêu cầu hiện tại,
  3. Viết mã chỉ đáp ứng các yêu cầu hiện tại, nhưng theo cách dễ dàng thay đổi sau này để đáp ứng các nhu cầu khác.

Trong trường hợp đầu tiên, thông thường kết thúc với mã được ghép chặt chẽ mà thiếu các bài kiểm tra đơn vị. Chắc chắn là viết nhanh, nhưng thật khó để kiểm tra. Và đó là một nỗi đau hoàng gia đúng để thay đổi sau này khi các yêu cầu thay đổi.

Trong trường hợp thứ hai, một lượng lớn thời gian được dành để cố gắng dự đoán nhu cầu trong tương lai. Và tất cả quá thường xuyên những yêu cầu dự đoán trong tương lai không bao giờ thành hiện thực. Đây có vẻ là kịch bản mà bạn đang mô tả. Đó là một sự lãng phí công sức hầu hết thời gian và dẫn đến mã phức tạp không cần thiết mà vẫn khó thay đổi khi một yêu cầu không được dự đoán sẽ xuất hiện.

Trường hợp cuối cùng là một trong những mục tiêu theo quan điểm của tôi. Sử dụng TDD hoặc các kỹ thuật tương tự để kiểm tra mã khi bạn đi và bạn sẽ kết thúc với mã được ghép lỏng lẻo, điều đó dễ sửa đổi nhưng vẫn nhanh chóng để viết. Và điều quan trọng là, bằng cách này, bạn tự nhiên tuân theo nhiều nguyên tắc RẮN: các lớp và hàm nhỏ; giao diện và phụ thuộc tiêm. Và bà Liskov thường được giữ hạnh phúc vì các lớp học đơn giản với các trách nhiệm duy nhất hiếm khi phạm lỗi với nguyên tắc thay thế của mình.

Khía cạnh duy nhất của RẮN không thực sự áp dụng ở đây là nguyên tắc mở / đóng. Đối với các thư viện và khung, điều này rất quan trọng. Đối với một ứng dụng độc lập, không quá nhiều. Thực sự đó là một trường hợp viết mã theo sau " SLID ": dễ viết (và đọc), dễ kiểm tra và dễ bảo trì.


một trong những câu trả lời yêu thích của tôi trên trang web này!
TheCatWhisperer

Tôi không chắc làm thế nào bạn kết luận rằng 1) khó kiểm tra hơn 3). Chắc chắn sẽ khó thay đổi hơn, nhưng tại sao bạn không thể kiểm tra? Nếu bất cứ điều gì, một phần mềm một đầu sẽ dễ dàng kiểm tra các yêu cầu hơn là một phần mềm tổng quát hơn.
Ông Lister

@MrLister Hai tay trong tay, 1. khó kiểm tra hơn 3. vì định nghĩa ngụ ý nó không được viết "theo cách dễ dàng thay đổi sau này để đáp ứng các nhu cầu khác."
Đánh dấu gian hàng

1
+0; IMVHO bạn đang hiểu sai (mặc dù theo cách thông thường) cách hoạt động của 'O' (đóng mở). Xem ví dụ codeblog.jonskeet.uk/2013/03/15/... - ngay cả trong codebases nhỏ, đó là chi tiết về việc có đơn vị khép kín mã (ví dụ như các lớp học, mô-đun, bao bì, bất cứ điều gì), có thể được thử nghiệm trong sự cô lập và bổ sung / loại bỏ khi có nhu cầu. Một ví dụ như vậy sẽ là một gói các phương thức tiện ích - bất kể bạn gói chúng như thế nào, chúng nên được 'đóng', nghĩa là khép kín và 'mở', nghĩa là có thể mở rộng theo một cách nào đó.
vaxquis

BTW, ngay cả chú Bob cũng đi theo hướng đó tại một thời điểm: Ý nghĩa [đóng mở] có nghĩa là bạn nên cố gắng đưa mã của mình vào một vị trí sao cho khi hành vi thay đổi theo cách dự kiến, bạn không cần phải quét thay đổi tất cả các mô-đun của hệ thống. Lý tưởng nhất là bạn sẽ có thể thêm hành vi mới bằng cách thêm mã mới và thay đổi ít hoặc không có mã cũ. Rõ ràng - điều này rõ ràng áp dụng ngay cả cho các ứng dụng nhỏ, nếu chúng được sửa đổi hoặc sửa chữa (và, IMVHO, đó thường là trường hợp, đặc biệt là khi liên quan đến các bản sửa lỗi cười )
vaxquis

8

Viễn cảnh bạn có thể bị sai lệch bởi kinh nghiệm cá nhân. Đây là một độ dốc trơn trượt của các sự kiện là chính xác, nhưng suy luận kết quả là không, mặc dù thoạt nhìn có vẻ đúng.

  • Các khung có phạm vi lớn hơn các dự án nhỏ.
  • Thực hành xấu là khó khăn hơn đáng kể để đối phó trong các cơ sở mã lớn hơn.
  • Xây dựng một khung (trung bình) đòi hỏi một nhà phát triển có kỹ năng hơn là xây dựng một dự án nhỏ.
  • Các nhà phát triển tốt hơn tuân theo thực tiễn tốt (RẮN) nhiều hơn.
  • Do đó, các khung có nhu cầu thực hành tốt cao hơn có xu hướng được xây dựng bởi các nhà phát triển có kinh nghiệm chặt chẽ hơn với thực tiễn tốt.

Điều này có nghĩa là khi bạn tương tác với các khung và các thư viện nhỏ hơn, mã thực hành tốt mà bạn sẽ tương tác sẽ thường được tìm thấy trong các khung lớn hơn.

Sai lầm này là rất phổ biến, ví dụ như mọi bác sĩ tôi từng được điều trị đều kiêu ngạo. Vì vậy, tôi kết luận rằng tất cả các bác sĩ đều kiêu ngạo. Những sai lầm luôn luôn bị thực hiện một chăn suy luận dựa trên kinh nghiệm cá nhân.

Trong trường hợp của bạn, có thể bạn chủ yếu có kinh nghiệm thực hành tốt trong các khung lớn hơn chứ không phải trong các thư viện nhỏ hơn. Quan sát cá nhân của bạn không sai, nhưng đó là bằng chứng giai thoại và không thể áp dụng phổ biến.


2 chế độ lập trình - tạo ra ít nhiều chính xác những gì được yêu cầu thông qua các yêu cầu và KISS (lập trình điển hình) hoặc tạo logic, dịch vụ rất chung chung và có thể tái sử dụng, cung cấp sự linh hoạt mà các nhà phát triển khác có thể cần (lập trình khung)

Bạn đang phần nào xác nhận điều này ở đây. Hãy nghĩ về một khuôn khổ là gì. Nó không phải là một ứng dụng. Đó là một "mẫu" tổng quát mà người khác có thể sử dụng để tạo ra tất cả các loại ứng dụng. Về mặt logic, điều đó có nghĩa là một khung được xây dựng theo logic trừu tượng hơn nhiều để mọi người có thể sử dụng.

Các nhà xây dựng khung không có khả năng sử dụng các phím tắt, vì họ thậm chí không biết các yêu cầu của các ứng dụng tiếp theo là gì. Xây dựng một khung vốn đã khuyến khích họ làm cho mã của họ có thể sử dụng được cho người khác.

Tuy nhiên, các nhà xây dựng ứng dụng có khả năng thỏa hiệp về hiệu quả logic vì họ tập trung vào việc cung cấp một sản phẩm. Mục tiêu chính của họ không phải là hoạt động của mã mà là trải nghiệm của người dùng.

Đối với một khung, người dùng cuối là một nhà phát triển khác, người sẽ tương tác với mã của bạn. Chất lượng mã của bạn quan trọng đối với người dùng cuối của bạn.
Đối với một ứng dụng, người dùng cuối là người không phải là nhà phát triển, người sẽ không tương tác với mã của bạn. Chất lượng mã của bạn không quan trọng đối với họ.

Đây chính xác là lý do tại sao các kiến ​​trúc sư của một nhóm phát triển thường đóng vai trò là người thực thi thực hành tốt. Chúng là một bước được loại bỏ khỏi việc phân phối sản phẩm, điều đó có nghĩa là chúng có xu hướng nhìn vào mã một cách khách quan, thay vì tập trung vào việc phân phối ứng dụng.


Nếu bạn thêm các điểm nhập cảnh trừu tượng này, bạn có thực sự đáp ứng các yêu cầu của người dùng hay bạn đang tạo một khung trên đầu trang của khung công nghệ và ngăn xếp hiện tại của bạn để giúp việc bổ sung trong tương lai dễ dàng hơn? Trong trường hợp nào bạn đang phục vụ lợi ích của khách hàng, hoặc của nhà phát triển?

Đây là một điểm thú vị và đó (theo kinh nghiệm của tôi) là lý do chính tại sao mọi người vẫn cố gắng biện minh để tránh thực hành tốt.

Để tóm tắt các điểm dưới đây: Bỏ qua thực hành tốt chỉ có thể được biện minh nếu các yêu cầu của bạn (như được biết hiện tại) là không thay đổi, và sẽ không bao giờ có bất kỳ thay đổi / bổ sung nào cho cơ sở mã. Spoiler alert: Điều đó hiếm khi xảy ra.
Ví dụ: khi tôi viết một ứng dụng bảng điều khiển 5 phút để xử lý một tệp cụ thể, tôi không sử dụng thực hành tốt. Bởi vì tôi sẽ chỉ sử dụng ứng dụng ngày hôm nay và không cần cập nhật trong tương lai (sẽ dễ dàng hơn để viết một ứng dụng khác nếu tôi cần một lần nữa).

Giả sử bạn có thể nhanh chóng xây dựng một ứng dụng trong 4 tuần và bạn có thể xây dựng ứng dụng đó đúng cách trong 6 tuần. Ngay từ cái nhìn đầu tiên, việc xây dựng một cách kém chất lượng có vẻ tốt hơn. Khách hàng nhận được ứng dụng của họ nhanh hơn và công ty phải dành ít thời gian hơn cho tiền lương của nhà phát triển. Thắng / thắng, phải không?

Tuy nhiên, đây là một quyết định được đưa ra mà không cần suy nghĩ trước. Do chất lượng của cơ sở mã hóa, việc thực hiện một thay đổi lớn đối với người được xây dựng một cách kém chất lượng sẽ mất 2 tuần, trong khi thực hiện các thay đổi tương tự đối với bản dựng được xây dựng đúng sẽ mất 1 tuần. Có thể có nhiều thay đổi trong số này sẽ xuất hiện trong tương lai.

Hơn nữa, có xu hướng thay đổi bất ngờ đòi hỏi nhiều công việc hơn bạn nghĩ ban đầu trong các cơ sở mã hóa được xây dựng một cách kém chất lượng, do đó có khả năng đẩy thời gian phát triển của bạn lên ba tuần thay vì hai tuần.

Và sau đó cũng có xu hướng lãng phí thời gian để săn bọ. Đây thường là trường hợp trong các dự án mà việc đăng nhập đã bị bỏ qua do hạn chế về thời gian hoặc không sẵn sàng thực hiện nó vì bạn đã lơ đãng làm việc theo giả định rằng sản phẩm cuối cùng sẽ hoạt động như mong đợi.

Nó thậm chí không cần phải là một bản cập nhật lớn. Tại công ty hiện tại của tôi, tôi đã thấy một số dự án được xây dựng nhanh chóng và bẩn thỉu, và khi lỗi / thay đổi nhỏ nhất cần được thực hiện do sự sai lệch trong các yêu cầu, dẫn đến phản ứng dây chuyền cần phải tái cấu trúc mô-đun sau mô-đun . Một số trong những dự án này đã kết thúc sụp đổ (và để lại một mớ hỗn độn không thể nhầm lẫn) trước khi chúng phát hành phiên bản đầu tiên.

Các quyết định rút gọn (lập trình nhanh và bẩn) chỉ có lợi nếu bạn có thể đảm bảo chắc chắn rằng các yêu cầu là chính xác và sẽ không bao giờ cần phải thay đổi. Theo kinh nghiệm của tôi, tôi chưa bao giờ bắt gặp một dự án nào là đúng.

Đầu tư thêm thời gian vào thực tiễn tốt là đầu tư vào tương lai. Các lỗi và thay đổi trong tương lai sẽ trở nên dễ dàng hơn rất nhiều khi cơ sở mã hiện tại được xây dựng dựa trên thực tiễn tốt. Nó sẽ được trả cổ tức chỉ sau hai hoặc ba thay đổi được thực hiện.


1
Đây là một câu trả lời tốt, nhưng tôi nên làm rõ rằng tôi không nói rằng chúng ta từ bỏ các thực hành tốt, nhưng chúng ta theo đuổi mức độ 'thực hành tốt' nào? Có phải là một thực hành tốt để trừu tượng ORM của bạn trong mọi dự án bởi vì bạn 'có thể cần phải trao đổi nó cho một dự án khác sau này? Tôi không nghĩ vậy, có một số mức độ khớp nối nhất định mà tôi sẵn sàng chấp nhận (ví dụ: tôi gắn với khung, ngôn ngữ, ORM, cơ sở dữ liệu đã được chọn). Nếu chúng ta tuân theo RẮN đến mức độ cực đoan, chúng ta có thực sự chỉ thực hiện khuôn khổ của riêng mình trên đầu trang được chọn không?
Igneous01

Bạn đang từ chối trải nghiệm của OP là "ngụy biện". Không mang tính xây dựng.
max630

@ max630 Tôi không phủ nhận điều đó. Tôi đã dành một phần tốt của câu trả lời giải thích tại sao quan sát của OP là hợp lệ.
Flater

1
@ Igneous01 RẮN không phải là một khung. RẮN là một sự trừu tượng, thường gặp hơn trong một khung. Khi thực hiện bất kỳ loại trừu tượng nào (bao gồm cả RẮN), luôn có một dòng hợp lý. Bạn không thể chỉ trừu tượng vì sự trừu tượng, bạn sẽ mất nhiều thời gian để tìm ra mã quá nổi bật, thật khó để theo dõi. Chỉ trừu tượng những gì bạn nghi ngờ hợp lý sẽ hữu ích cho bạn trong tương lai. Tuy nhiên, đừng rơi vào cái bẫy giả định rằng bạn bị ràng buộc với máy chủ cơ sở dữ liệu hiện tại của bạn. Bạn không bao giờ biết cơ sở dữ liệu mới nào sẽ được phát hành vào ngày mai.
Flater

@ Igneous01 Nói cách khác, bạn có ý tưởng đúng đắn khi không muốn trừu tượng hóa mọi thứ, nhưng tôi có cảm giác bạn đang nghiêng mình quá xa theo hướng đó. Rất phổ biến đối với các nhà phát triển khi cho rằng các yêu cầu hiện tại được đặt ra và sau đó đưa ra quyết định kiến ​​trúc dựa trên giả định (mong muốn) đó.
Flater

7

Làm thế nào để RẮN biến mã đơn giản thành mã khung? Tôi không phải là người kiên quyết cho RẮN bằng mọi cách nhưng thực sự không rõ ý của bạn ở đây là gì.

  • KISS là bản chất của Nguyên tắc Trách nhiệm của S ingle.
  • Không có gì trong bút O / Nguyên tắc khép kín (ít nhất là theo tôi hiểu, nó thấy Jon Skeet ) đi ngược lại việc viết mã để làm tốt một việc. (Trong thực tế, mã càng tập trung chặt chẽ, phần đóng kín càng quan trọng.)
  • Các L iskov Thay Nguyên tắc không nói rằng bạn phải để cho người phân lớp lớp học của bạn. Nó nói rằng nếu bạn phân lớp các lớp của bạn, các lớp con của bạn sẽ thực hiện hợp đồng của các siêu lớp của chúng. Đó chỉ là thiết kế OO tốt. (Và nếu bạn không có bất kỳ lớp con nào, nó sẽ không áp dụng.)
  • KISS cũng là bản chất của Nguyên tắc phân chia I nterface.
  • Các D ependency Inversion Nguyên tắc là người duy nhất tôi có thể nhìn thấy từ xa áp dụng, nhưng tôi nghĩ đó là rộng rãi hiểu lầm và bị thổi phồng. Điều đó không có nghĩa là bạn phải tiêm mọi thứ với Guice hoặc Spring. Nó chỉ có nghĩa là bạn nên trừu tượng khi thích hợp và không phụ thuộc vào chi tiết thực hiện.

Tôi thừa nhận bản thân tôi không nghĩ theo các điều khoản RẮN, bởi vì tôi đã đến trường lập trình Gang of FourJosh Bloch , không phải trường Bob Martin. Nhưng tôi thực sự nghĩ rằng nếu bạn nghĩ rằng RẮN RẮN RỪNG ĐỔI BẠC, thêm nhiều lớp vào ngăn xếp công nghệ, thì bạn đã đọc nhầm.


PS Đừng bán những lợi ích của UX tốt hơn cho nhà phát triển. Mã dành phần lớn cuộc đời của nó trong bảo trì. Một nhà phát triển là bạn .


1
Về SRP - người ta có thể lập luận rằng bất kỳ lớp nào có hàm tạo đều vi phạm SRP, bởi vì bạn có thể giảm trách nhiệm đó cho một nhà máy. Về OCP - đây thực sự là một vấn đề ở cấp độ khung, bởi vì một khi bạn xuất bản một giao diện để sử dụng ra bên ngoài, bạn không thể sửa đổi nó. Nếu giao diện chỉ được sử dụng trong dự án của bạn, thì bạn có thể thay đổi hợp đồng, vì bạn có quyền thay đổi hợp đồng trong mã của riêng bạn. Về ISP - người ta có thể lập luận rằng một giao diện nên được xác định cho từng hành động riêng lẻ (do đó duy trì SRP) và mối quan tâm bên ngoài người dùng.
Igneous01

3
1) người ta có thể, nhưng tôi nghi ngờ bất cứ ai đáng nghe bao giờ có. 2) bạn có thể ngạc nhiên khi một dự án có thể phát triển đến một kích thước nhanh chóng đến mức tự do sửa đổi giao diện nội bộ trở thành một ý tưởng tồi. 3) xem cả 1) và 2). Đủ để nói tôi nghĩ rằng bạn đang đọc quá nhiều vào cả ba nguyên tắc. Nhưng ý kiến ​​không thực sự là nơi để giải quyết những tranh luận này; Tôi đề nghị bạn đặt ra mỗi câu hỏi như một câu hỏi riêng biệt và xem bạn nhận được loại câu trả lời nào.
David Moles

4
@ Igneous01 Sử dụng logic đó, bạn cũng có thể từ bỏ getters và setters, vì bạn có thể tạo một lớp riêng cho mỗi setter biến và một cho mỗi getter. IE: class A{ int X; int Y; } class A_setX{ f(A a, int N) { a.X = N; }} class A_getX{ int f(A a) { return X; }} class A_setY ... etc.Tôi nghĩ rằng bạn đang xem xét nó từ quan điểm quá meta với yêu cầu nhà máy của bạn. Khởi tạo không phải là một khía cạnh của vấn đề tên miền.
Aaron

@Aaron Cái này. Mọi người có thể sử dụng RẮN để đưa ra những lập luận xấu, nhưng điều đó không có nghĩa là làm những điều xấu = theo sau RID RÀNG.
David Moles
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.