Không quan trọng việc kết hợp chặt chẽ giữa một thứ với nhau như thế nào nếu điều đó không bao giờ thay đổi. Nhìn chung, tôi đã thấy nó hiệu quả hơn trong nhiều năm qua để tập trung vào việc tìm kiếm ít lý do hơn để thay đổi, tìm kiếm sự ổn định, hơn là làm cho chúng dễ dàng thay đổi hơn bằng cách cố gắng đạt được hình thức khớp nối lỏng lẻo nhất có thể.
Việc tách riêng tôi thấy rất hữu ích, đến mức đôi khi tôi thích sao chép mã khiêm tốn cho các gói tách rời. Để làm ví dụ cơ bản, tôi có lựa chọn sử dụng thư viện toán học của mình để triển khai thư viện hình ảnh. Tôi đã không và chỉ sao chép một số hàm toán học cơ bản không đáng để sao chép.
Bây giờ thư viện hình ảnh của tôi hoàn toàn độc lập với thư viện toán học theo cách mà bất kể loại thay đổi nào tôi thực hiện đối với lib toán học của tôi, nó sẽ không ảnh hưởng đến thư viện hình ảnh. Đó là đặt sự ổn định lên trên hết. Hiện tại thư viện hình ảnh ổn định hơn, vì có rất ít lý do để thay đổi, vì nó được tách ra khỏi bất kỳ thư viện nào khác có thể thay đổi (ngoài thư viện tiêu chuẩn C hy vọng sẽ không bao giờ thay đổi). Như một phần thưởng, nó cũng dễ dàng triển khai khi nó chỉ là một thư viện độc lập không yêu cầu kéo theo một loạt các lib khác để xây dựng và sử dụng nó.
Sự ổn định là rất hữu ích với tôi. Tôi thích xây dựng một bộ sưu tập mã được kiểm tra tốt, có ngày càng ít lý do để thay đổi trong tương lai. Đó không phải là một giấc mơ xa vời; Tôi có mã C tôi đã sử dụng và sử dụng lại từ cuối những năm 80 mà không thay đổi gì kể từ đó. Nó được thừa nhận là những thứ cấp thấp như mã định hướng pixel và liên quan đến hình học trong khi rất nhiều thứ cấp cao hơn của tôi trở nên lỗi thời, nhưng nó vẫn là thứ giúp ích rất nhiều cho xung quanh. Điều đó hầu như luôn có nghĩa là một thư viện dựa vào ngày càng ít thứ hơn, nếu không có gì bên ngoài cả. Độ tin cậy tăng lên và tăng lên nếu phần mềm của bạn ngày càng phụ thuộc vào nền tảng ổn định mà tìm thấy ít hoặc không có lý do để thay đổi. Ít bộ phận chuyển động thực sự tốt đẹp, ngay cả trong thực tế, các bộ phận chuyển động có số lượng lớn hơn nhiều so với các bộ phận ổn định.
Khớp nối lỏng lẻo nằm trong cùng một tĩnh mạch, nhưng tôi thấy rằng khớp nối lỏng lẻo kém ổn định hơn nhiều so với không khớp nối. Trừ khi bạn làm việc trong một nhóm với các nhà thiết kế giao diện và khách hàng vượt trội hơn nhiều so với những gì tôi từng làm việc, thậm chí các giao diện thuần túy thường tìm lý do để thay đổi theo cách vẫn gây ra sự phá vỡ tầng trong mã. Ý tưởng này có thể đạt được sự ổn định bằng cách hướng sự phụ thuộc vào trừu tượng hơn là cụ thể chỉ hữu ích nếu thiết kế giao diện dễ dàng có được ngay lần đầu tiên so với việc thực hiện. Tôi thường thấy nó đảo ngược nơi mà một nhà phát triển có thể đã tạo ra một triển khai rất tốt, nếu không tuyệt vời, đưa ra các yêu cầu thiết kế mà họ nghĩ họ nên đáp ứng, chỉ để thấy trong tương lai các yêu cầu thiết kế thay đổi hoàn toàn.
Vì vậy, tôi thích ưu tiên sự ổn định và tách rời hoàn toàn để ít nhất tôi có thể tự tin nói: "Thư viện biệt lập nhỏ bé này đã được sử dụng trong nhiều năm và được bảo đảm bằng thử nghiệm kỹ lưỡng gần như không có khả năng yêu cầu thay đổi cho dù có xảy ra trong thế giới hỗn loạn bên ngoài . " Nó mang lại cho tôi một chút tỉnh táo bất kể loại thay đổi thiết kế nào được gọi cho bên ngoài.
Khớp nối và ổn định, ví dụ ECS
Tôi cũng thích các hệ thống thành phần thực thể và chúng giới thiệu rất nhiều khớp nối chặt chẽ bởi vì hệ thống phụ thuộc vào thành phần tất cả truy cập và thao tác trực tiếp dữ liệu thô, như vậy:
Tất cả các phụ thuộc ở đây là khá chặt chẽ vì các thành phần chỉ lộ dữ liệu thô. Các phần phụ thuộc không chảy theo trừu tượng, chúng chuyển sang dữ liệu thô , điều đó có nghĩa là mỗi hệ thống có lượng kiến thức tối đa có thể về từng loại thành phần mà chúng yêu cầu truy cập. Các thành phần không có chức năng với tất cả các hệ thống truy cập và giả mạo dữ liệu thô. Tuy nhiên, thật dễ dàng để suy luận về một hệ thống như thế này vì nó quá phẳng. Nếu một kết cấu xuất hiện khó khăn, thì bạn sẽ biết ngay với hệ thống này rằng chỉ có các thành phần kết cấu và vẽ hệ thống truy cập, và bạn có thể nhanh chóng loại trừ hệ thống kết xuất vì nó chỉ đọc từ kết cấu.
Trong khi đó, một sự thay thế kết hợp lỏng lẻo có thể là thế này:
... Với tất cả các phụ thuộc chảy vào các hàm trừu tượng, không phải dữ liệu và mọi thứ trong sơ đồ đó phơi bày một giao diện công cộng và chức năng của chính nó. Ở đây tất cả các phụ thuộc có thể rất lỏng lẻo. Các đối tượng thậm chí có thể không phụ thuộc trực tiếp vào nhau và tương tác với nhau thông qua các giao diện thuần túy. Tuy nhiên, rất khó để suy luận về hệ thống này, đặc biệt là nếu có sự cố xảy ra, do các mớ tương tác phức tạp. Cũng sẽ có nhiều tương tác (nhiều khớp nối hơn, mặc dù lỏng hơn) so với ECS vì các thực thể phải biết về các thành phần mà chúng tổng hợp, ngay cả khi chúng chỉ biết về giao diện chung trừu tượng của nhau.
Ngoài ra, nếu có thay đổi thiết kế đối với bất cứ điều gì, bạn sẽ nhận được nhiều sự phá vỡ tầng hơn ECS, và thường sẽ có nhiều lý do và cám dỗ cho thay đổi thiết kế vì mỗi điều đều cố gắng cung cấp một giao diện hướng đối tượng và trừu tượng đẹp. Điều đó ngay lập tức đi kèm với ý tưởng rằng mỗi một điều nhỏ nhặt sẽ cố gắng áp đặt các hạn chế và hạn chế đối với thiết kế, và những hạn chế đó thường là những gì bảo đảm thay đổi thiết kế. Chức năng bị hạn chế hơn nhiều và phải đưa ra rất nhiều giả định thiết kế so với dữ liệu thô.
Trên thực tế, tôi đã tìm thấy loại hệ thống ECS "phẳng" ở trên dễ hiểu hơn rất nhiều so với các hệ thống được ghép lỏng lẻo nhất với một mạng nhện phức tạp của sự phụ thuộc lỏng lẻo và quan trọng nhất với tôi, tôi thấy rất ít lý do đối với phiên bản ECS cần phải thay đổi bất kỳ thành phần hiện có nào vì các thành phần phụ thuộc không có trách nhiệm ngoại trừ việc cung cấp dữ liệu phù hợp cần thiết cho các hệ thống hoạt động. So sánh khó khăn trong việc thiết kế IMotion
giao diện thuần túy và đối tượng chuyển động cụ thể thực hiện giao diện đó cung cấp chức năng tinh vi trong khi cố gắng duy trì bất biến trên dữ liệu riêng tư so với thành phần chuyển động chỉ cần cung cấp dữ liệu thô có liên quan để giải quyết vấn đề và không bận tâm với chức năng.
Chức năng rất khó để có được quyền hơn dữ liệu, đó là lý do tại sao tôi nghĩ rằng thường là tốt hơn để hướng luồng phụ thuộc vào dữ liệu. Rốt cuộc, có bao nhiêu thư viện vector / ma trận ngoài kia? Có bao nhiêu trong số chúng sử dụng cùng một biểu diễn dữ liệu và chỉ khác nhau một cách tinh tế về chức năng? Vô số, nhưng chúng tôi vẫn có rất nhiều mặc dù biểu diễn dữ liệu giống hệt nhau bởi vì chúng tôi muốn sự khác biệt tinh tế trong chức năng. Có bao nhiêu thư viện hình ảnh ngoài kia? Có bao nhiêu trong số chúng đại diện cho pixel theo một cách khác biệt và độc đáo? Hầu như không, và một lần nữa cho thấy chức năng không ổn định hơn nhiều và thiên về thay đổi thiết kế so với dữ liệu trong nhiều tình huống. Tất nhiên, tại một số điểm chúng tôi cần chức năng, nhưng bạn có thể thiết kế các hệ thống trong đó phần lớn các phụ thuộc chảy vào dữ liệu, và không hướng tới sự trừu tượng hay chức năng nói chung. Như vậy sẽ được ưu tiên ổn định trên khớp nối.
Các hàm ổn định nhất tôi từng viết (loại tôi đã sử dụng và sử dụng lại từ cuối những năm 80 mà không phải thay đổi chúng) đều là những hàm dựa trên dữ liệu thô, giống như một hàm hình học chỉ chấp nhận một mảng số float và số nguyên, không phải số nguyên phụ thuộc vào một Mesh
đối tượng hoặc IMesh
giao diện phức tạp , hoặc phép nhân vectơ / ma trận chỉ phụ thuộc vào float[]
hoặc double[]
, không phụ thuộc vào FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse
.