Tách
Cuối cùng, đó là về việc tách rời tôi vào cuối ngày ở mức thiết kế cơ bản nhất mà không có sắc thái đặc trưng của trình biên dịch và trình liên kết của chúng tôi. Ý tôi là bạn có thể làm những việc như làm cho mỗi tiêu đề chỉ xác định một lớp, sử dụng pimpls, khai báo chuyển tiếp thành các loại chỉ cần khai báo, không xác định, thậm chí có thể sử dụng các tiêu đề chỉ chứa khai báo chuyển tiếp (ví dụ <iosfwd>
:), một tiêu đề cho mỗi tệp nguồn , tổ chức hệ thống một cách nhất quán dựa trên loại điều được khai báo / định nghĩa, v.v.
Kỹ thuật để giảm "phụ thuộc thời gian biên dịch"
Và một số kỹ thuật có thể giúp ích khá nhiều nhưng bạn có thể thấy mình cạn kiệt các thực tiễn này và vẫn thấy tệp nguồn trung bình trong hệ thống của bạn cần một đoạn mở đầu gồm hai trang #include
Chỉ thị làm bất cứ điều gì có ý nghĩa với thời gian xây dựng tăng vọt nếu bạn tập trung quá nhiều vào việc giảm phụ thuộc thời gian biên dịch ở cấp tiêu đề mà không giảm phụ thuộc logic trong thiết kế giao diện của bạn, và trong khi đó có thể không được coi là "tiêu đề spaghetti" Vẫn nói rằng nó chuyển sang các vấn đề bất lợi tương tự đối với năng suất trong thực tế. Vào cuối ngày, nếu các đơn vị biên dịch của bạn vẫn yêu cầu một khối lượng thông tin có thể nhìn thấy để làm bất cứ điều gì, thì nó sẽ chuyển sang tăng thời gian xây dựng và nhân lên những lý do bạn phải quay lại và phải thay đổi mọi thứ trong khi tạo nhà phát triển cảm thấy như họ đang làm cho hệ thống chỉ cố gắng hoàn thành việc mã hóa hàng ngày của họ. Nó '
Ví dụ, bạn có thể làm cho mỗi hệ thống con cung cấp một tệp tiêu đề và giao diện rất trừu tượng. Nhưng nếu các hệ thống con không tách rời nhau, thì bạn sẽ nhận được một cái gì đó giống với spaghetti một lần nữa với các giao diện hệ thống con tùy thuộc vào các giao diện hệ thống con khác với biểu đồ phụ thuộc trông giống như một mớ hỗn độn để hoạt động.
Tuyên bố chuyển tiếp đến các loại bên ngoài
Trong tất cả các kỹ thuật tôi đã cạn kiệt để cố gắng có được một cơ sở mã cũ mất hai giờ để xây dựng trong khi các nhà phát triển đôi khi phải đợi 2 ngày để đến lượt CI trên các máy chủ xây dựng của chúng tôi (bạn gần như có thể tưởng tượng những cỗ máy xây dựng đó là những con thú kiệt sức đang cố gắng điên cuồng để theo kịp và thất bại trong khi các nhà phát triển thúc đẩy các thay đổi của họ), điều đáng nghi ngờ nhất với tôi là chuyển tiếp khai báo các loại được xác định trong các tiêu đề khác. Và tôi đã xoay sở để có được cơ sở mã hóa đó xuống còn 40 phút hoặc lâu hơn sau nhiều năm thực hiện việc này trong các bước tăng dần trong khi cố gắng giảm "spaghetti tiêu đề", cách thực hành đáng nghi ngờ nhất trong nhận thức (như khiến tôi mất đi bản chất cơ bản của thiết kế trong khi đường hầm có tầm nhìn về sự phụ thuộc lẫn nhau của tiêu đề) là các kiểu khai báo chuyển tiếp được định nghĩa trong các tiêu đề khác.
Nếu bạn tưởng tượng một Foo.hpp
tiêu đề có cái gì đó như:
#include "Bar.hpp"
Và nó chỉ sử dụng Bar
trong tiêu đề một cách yêu cầu khai báo, không định nghĩa. sau đó nó có vẻ như không có trí tuệ để tuyên bố class Bar;
để tránh làm cho định nghĩa Bar
hiển thị trong tiêu đề. Ngoại trừ trong thực tế thường bạn sẽ tìm thấy hầu hết các đơn vị biên dịch sử dụng Foo.hpp
cuối cùng vẫn cần Bar
phải được xác định với gánh nặng thêm là phải đặt Bar.hpp
chúng lên trên Foo.hpp
hoặc bạn gặp phải một kịch bản khác thực sự giúp ích và 99 % các đơn vị biên dịch của bạn có thể hoạt động mà không bao gồm Bar.hpp
, ngoại trừ sau đó nó đặt ra câu hỏi thiết kế cơ bản hơn (hoặc ít nhất là tôi nghĩ nó nên hiện nay) về lý do tại sao họ cần phải xem tuyên bố Bar
và tại saoFoo
thậm chí cần phải bận tâm để biết về nó nếu nó không liên quan đến hầu hết các trường hợp sử dụng (tại sao lại gây gánh nặng cho một thiết kế với sự phụ thuộc vào một thiết bị khác hầu như chưa từng sử dụng?).
Bởi vì khái niệm, chúng tôi đã không thực sự tách rời Foo
khỏi Bar
. Chúng tôi đã làm cho nó để tiêu đề Foo
không cần nhiều thông tin về tiêu đề Bar
và điều đó gần như không đáng kể như một thiết kế thực sự làm cho hai cái này hoàn toàn độc lập với nhau.
Scripting nhúng
Điều này thực sự dành cho các cơ sở mã quy mô lớn hơn nhưng một kỹ thuật khác tôi thấy vô cùng hữu ích là sử dụng ngôn ngữ kịch bản nhúng cho ít nhất là các phần cấp cao nhất trong hệ thống của bạn. Tôi thấy rằng tôi đã có thể nhúng Lua trong một ngày và nó có thể gọi tất cả các lệnh trong hệ thống của chúng tôi một cách thống nhất (các lệnh rất trừu tượng, rất may). Thật không may, tôi đã gặp phải một rào cản nơi các nhà phát triển không tin vào việc giới thiệu một ngôn ngữ khác và, có lẽ kỳ lạ nhất, với hiệu suất là sự nghi ngờ lớn nhất của họ. Tuy nhiên, trong khi tôi có thể hiểu các mối quan tâm khác, hiệu suất sẽ không thành vấn đề nếu chúng tôi chỉ sử dụng tập lệnh để gọi các lệnh khi người dùng nhấp vào nút, ví dụ, thực hiện không có vòng lặp quá lớn của riêng họ (chúng tôi đang cố gắng làm gì, lo lắng về sự khác biệt của nano giây trong thời gian phản hồi cho một lần bấm nút?).
Thí dụ
Trong khi đó, cách hiệu quả nhất mà tôi từng chứng kiến sau khi sử dụng hết các kỹ thuật để giảm thời gian biên dịch trong các cơ sở mã lớn là các kiến trúc thực sự làm giảm lượng thông tin cần thiết cho bất kỳ một thứ nào trong hệ thống để hoạt động, không chỉ tách một tiêu đề từ một trình biên dịch khác phối cảnh nhưng yêu cầu người dùng các giao diện này phải làm những gì họ cần làm trong khi biết (cả từ quan điểm của con người và trình biên dịch, việc tách rời thực sự vượt ra ngoài phụ thuộc trình biên dịch) ở mức tối thiểu.
ECS chỉ là một ví dụ (và tôi không khuyên bạn nên sử dụng một ví dụ), nhưng việc gặp nó cho tôi thấy rằng bạn có thể có một số bộ mã thực sự hoành tráng vẫn tạo ra một cách đáng ngạc nhiên trong khi vui vẻ sử dụng các mẫu và nhiều tính năng khác bởi vì ECS, về bản chất, tạo ra một kiến trúc tách rời, trong đó các hệ thống chỉ cần biết về cơ sở dữ liệu ECS và thường chỉ có một số loại thành phần (đôi khi chỉ là một) để thực hiện công việc của chúng:
Thiết kế, thiết kế, thiết kế
Và những kiểu thiết kế kiến trúc tách rời này ở cấp độ con người, ở mức độ khái niệm có hiệu quả hơn về mặt tối thiểu hóa thời gian biên dịch so với bất kỳ kỹ thuật nào tôi đã khám phá ở trên khi codebase của bạn phát triển và tăng trưởng, bởi vì sự tăng trưởng đó không đạt mức trung bình của bạn đơn vị biên dịch nhân số lượng thông tin cần thiết khi biên dịch và thời gian liên kết để hoạt động (bất kỳ hệ thống nào yêu cầu nhà phát triển trung bình của bạn bao gồm một khối lượng công cụ để làm bất cứ điều gì cũng cần chúng và không chỉ trình biên dịch biết về rất nhiều thông tin để làm bất cứ điều gì ). Nó cũng có nhiều lợi ích hơn giảm thời gian xây dựng và gỡ rối các tiêu đề, vì điều đó cũng có nghĩa là các nhà phát triển của bạn không cần biết nhiều về hệ thống ngoài những gì được yêu cầu ngay lập tức để làm điều gì đó với nó.
Ví dụ, nếu bạn có thể thuê một nhà phát triển vật lý chuyên gia để phát triển một công cụ vật lý cho trò chơi AAA của bạn trải rộng hàng triệu LỘC và anh ta có thể bắt đầu rất nhanh trong khi biết thông tin tối thiểu tuyệt đối về những thứ như các loại và giao diện có sẵn cũng như các khái niệm hệ thống của bạn, sau đó sẽ tự nhiên chuyển sang giảm lượng thông tin cho cả anh ấy và trình biên dịch để yêu cầu xây dựng công cụ vật lý của anh ấy, và tương tự như vậy để giảm thời gian xây dựng trong khi nói chung là không có gì giống với spaghetti bất cứ nơi nào trong hệ thống. Và đó là những gì tôi đề nghị ưu tiên hơn tất cả các kỹ thuật khác: cách bạn thiết kế hệ thống của mình. Làm cạn kiệt các kỹ thuật khác sẽ đóng băng trên đầu nếu bạn làm điều đó trong khi, nếu không,