Tiêu chí cho thiết kế xấu

Cuộc sống hoạt động khá đơn giản: thông thường, để trở nên thông minh, bạn chỉ cần không làm những điều ngu ngốc. Điều này cũng áp dụng cho việc phát triển phần mềm: trong hầu hết các trường hợp, để làm tốt một việc gì đó, bạn chỉ cần làm việc đó không tệ.

Hầu hết các lập trình viên đã có kinh nghiệm với các bộ phận của hệ thống được thiết kế tồi. Nhưng đáng buồn hơn nữa, hầu hết các bạn sẽ có trải nghiệm đáng buồn khi nhận ra rằng mình là tác giả của một hệ thống như vậy. Chúng tôi muốn điều tốt nhất, nhưng hóa ra như mọi khi.

Hầu hết các nhà phát triển không khao khát kiến ​​trúc tồi, và đối với nhiều hệ thống, có lúc họ bắt đầu nói rằng kiến ​​trúc của nó thật tồi tệ. Tại sao chuyện này đang xảy ra? Thiết kế kiến ​​trúc đã tệ ngay từ đầu hay nó đã trở nên tệ theo thời gian?

Gốc rễ của vấn đề này là do thiếu định nghĩa về thiết kế “xấu”.

Đối với tôi, có vẻ như chính sự hiểu biết về chất lượng của thiết kế và lý do dẫn đến sự “suy tàn” của nó mới là những phẩm chất quan trọng nhất đối với bất kỳ lập trình viên nào. Như trong hầu hết các trường hợp khác, điều chính yếu là xác định vấn đề và việc giải quyết nó sẽ là vấn đề của công nghệ.

Định nghĩa về “thiết kế xấu”

Nếu bạn quyết định khoe khoang về mã của mình trước mặt một lập trình viên đồng nghiệp, rất có thể bạn sẽ bị chế nhạo: “Ai làm cái này?”, 'Tại sao lại như vậy?' và "Tôi sẽ làm những điều khác biệt." Điều này xảy ra rất thường xuyên.

Tất cả mọi người đều khác nhau, nhưng bạn vẫn viết mã cho các lập trình viên đồng nghiệp của mình, vì vậy trong quá trình phát triển từng tính năng, bạn luôn cần có giai đoạn đánh giá khi người khác xem mã của bạn.

Nhưng ngay cả khi nhiều thứ có thể được thực hiện theo những cách khác nhau, vẫn có một bộ tiêu chí mà tất cả các nhà phát triển sẽ đồng ý. Bất kỳ đoạn mã nào thỏa mãn các yêu cầu của nó nhưng vẫn thể hiện một (hoặc nhiều) đặc điểm là thiết kế tồi.

Thiết kế xấu:

  • Khó thay đổi vì bất kỳ thay đổi nào cũng ảnh hưởng đến quá nhiều phần khác của hệ thống. ( Độ cứng , Độ cứng).
  • Khi các thay đổi được thực hiện, các phần khác của hệ thống bị hỏng bất ngờ. ( Mỏng manh , Mong manh).
  • Mã này khó sử dụng lại trong ứng dụng khác vì quá khó để lấy mã đó ra khỏi ứng dụng hiện tại. ( Bất động , Bất động).

Và điều buồn cười là hầu như không thể tìm thấy một phần nào của hệ thống không có bất kỳ đặc điểm nào trong số này (nghĩa là linh hoạt, đáng tin cậy và có thể tái sử dụng), đáp ứng yêu cầu, đồng thời thiết kế của nó rất tệ .

Do đó, chúng ta có thể sử dụng ba đặc điểm này để xác định rõ ràng liệu một thiết kế là “xấu” hay “tốt”.

Nguyên nhân của "Thiết kế xấu"

Điều gì làm cho một thiết kế trở nên cứng nhắc, giòn và bất động? Sự phụ thuộc lẫn nhau cứng nhắc của các mô-đun.

Một thiết kế là cứng nhắc nếu nó không thể dễ dàng thay đổi. Sự cứng nhắc này là do thực tế là một thay đổi đơn lẻ đối với một đoạn mã trong hệ thống dệt dẫn đến các thay đổi xếp tầng trong các mô-đun phụ thuộc. Điều này luôn xảy ra khi một người đang viết mã.

Điều này ngay lập tức làm phức tạp toàn bộ quá trình phát triển thương mại: khi nhà thiết kế hoặc nhà phát triển không thể dự đoán số lượng thay đổi theo tầng, thì không thể ước tính tác động của thay đổi đó. Do đó, họ cố gắng trì hoãn những thay đổi đó vô thời hạn.

Và điều này lại làm cho chi phí thay đổi không thể đoán trước. Đối mặt với sự không chắc chắn như vậy, các nhà quản lý không muốn thay đổi, vì vậy thiết kế chính thức trở nên cứng nhắc.

Tại một thời điểm nào đó, dự án của bạn vượt qua “chân trời sự kiện” và chắc chắn sẽ rơi vào “hố đen” của kiến ​​trúc cứng nhắc.

Mong manh là xu hướng của một hệ thống bị hỏng ở nhiều nơi sau một lần thay đổi. Thông thường các vấn đề mới xảy ra ở những nơi không liên quan về mặt khái niệm với nơi thay đổi. Sự mong manh như vậy làm suy yếu nghiêm trọng niềm tin vào thiết kế và bảo trì hệ thống.

Đây thường là trường hợp khi không có phương pháp riêng tư. Chỉ cần công khai tất cả các phương thức là đủ và bạn sẽ phải cam chịu sự xuất hiện của một kiến ​​​​trúc mong manh. Đóng gói giúp giải quyết vấn đề này ở cấp độ vi mô. Nhưng ở cấp độ vĩ mô, bạn cần một kiến ​​trúc mô-đun.

Khi một dự án có kiến ​​trúc mong manh, các nhà phát triển không thể đảm bảo chất lượng của sản phẩm.

Những thay đổi đơn giản trong một phần của ứng dụng dẫn đến lỗi ở những phần không liên quan khác. Sửa những lỗi này thậm chí còn dẫn đến nhiều vấn đề hơn và quá trình hộ tống biến thành một con chó nổi tiếng đuổi theo đuôi của chính nó.

Thiết kế bất động khi những phần cần thiết của hệ thống bị ràng buộc chặt chẽ với những chi tiết không mong muốn khác. Quá nhiều mã của riêng họ, cách tiếp cận và giải pháp độc đáo của riêng họ.

Bạn có nhớ trình ghi nhật ký JUL, mà các nhà phát triển đã đưa ra các mức ghi nhật ký của riêng họ mà không có lý do chính đáng không? Đây chỉ là trường hợp.

Để cung cấp cho nhà thiết kế ý tưởng về việc sử dụng lại một thiết kế hiện có dễ dàng như thế nào, chỉ cần nghĩ về việc sử dụng nó trong một ứng dụng mới sẽ dễ dàng như thế nào là đủ.

Nếu thiết kế được liên kết chặt chẽ, thì nhà thiết kế này sẽ phải kinh hoàng với khối lượng công việc cần thiết để tách các phần cần thiết của hệ thống khỏi các chi tiết không cần thiết. Trong hầu hết các trường hợp, một thiết kế như vậy không thể tái sử dụng được, vì chi phí tách nó ra cao hơn so với việc phát triển nó từ đầu.

Mức độ liên quan

Mọi thứ thay đổi, nhưng mọi thứ vẫn như cũ. (Tục ngữ Trung Quốc)

Những câu hỏi rất hay đã được nêu ra ở trên. Những nguy hiểm của các hệ thống mong manh và cứng nhắc là gì? Có, bởi vì quá trình quản lý một dự án như vậy trở nên không thể đoán trước và không thể kiểm soát được. Và giá là cắt cổ.

Làm cách nào để người quản lý có thể đồng ý hoặc không đồng ý thêm một số tính năng nếu anh ta không biết thực sự sẽ mất bao nhiêu thời gian? Làm thế nào để ưu tiên các nhiệm vụ nếu bạn không thể ước tính đầy đủ thời gian và mức độ phức tạp của việc thực hiện chúng?

Và làm thế nào các nhà phát triển có thể trả hết khoản nợ kỹ thuật tương tự khi chúng tôi sẽ cào vào việc trả nó và chúng tôi không thể hiểu chúng tôi sẽ cào bao nhiêu cho đến khi chúng tôi cào?

Các vấn đề về tái sử dụng mã hoặc thử nghiệm cũng rất liên quan. Các bài kiểm tra đơn vị không chỉ phục vụ để kiểm tra một số giả định về đơn vị được kiểm tra, mà còn để xác định mức độ gắn kết của nó và có thể đóng vai trò là chỉ số tái sử dụng.

Đây là một trích dẫn của Bob Martin cho trường hợp này: “Để sử dụng lại mã của bạn, bạn cần nỗ lực sử dụng lại nó ít hơn so với chi phí phát triển từ đầu . ” Nếu không, thậm chí sẽ không ai bận tâm đến vấn đề này.

Việc sử dụng các nguyên tắc và mẫu thiết kế phục vụ một mục đích - làm cho thiết kế trở nên tốt đẹp. Nếu việc sử dụng chúng không mang lại cho bạn bất kỳ lợi ích nào (hoặc ngược lại, vi phạm các nguyên tắc của “thiết kế tốt”), thì có điều gì đó không ổn trong nhà kính của bạn và có lẽ, công cụ này đã bắt đầu được sử dụng cho các mục đích khác.