Tôi khá là người thực dụng, nhưng mối quan tâm chính của tôi ở đây là bạn có thể cho phép điều này ConfigBlock
chi phối các thiết kế giao diện của bạn theo một cách có thể xấu. Khi bạn có một cái gì đó như thế này:
explicit MyGreatClass(const ConfigBlock& config);
... một giao diện phù hợp hơn có thể như thế này:
MyGreatClass(int foo, float bar, const string& baz);
... Trái ngược với việc anh đào hái những foo/bar/baz
cánh đồng này trong số lượng lớn ConfigBlock
.
Thiết kế giao diện lười biếng
Về mặt tích cực, kiểu thiết kế này giúp bạn dễ dàng thiết kế giao diện ổn định cho nhà xây dựng của mình, ví dụ: nếu cuối cùng bạn cần một cái gì đó mới, bạn có thể tải nó vào ConfigBlock
(có thể không có bất kỳ thay đổi mã nào) và sau đó là cherry- chọn bất cứ thứ gì mới mà bạn cần mà không có bất kỳ loại thay đổi giao diện nào, chỉ thay đổi cách thực hiện MyGreatClass
.
Vì vậy, cả hai đều là một chuyên gia và lừa đảo rằng điều này giải phóng bạn trong việc thiết kế một giao diện được suy nghĩ cẩn thận hơn, chỉ chấp nhận các đầu vào mà nó thực sự cần. Nó áp dụng suy nghĩ, "Chỉ cần cung cấp cho tôi kho dữ liệu khổng lồ này, tôi sẽ chọn ra những gì tôi cần từ nó" trái ngược với một cái gì đó giống như, "Những thông số chính xác này là những gì giao diện này cần để hoạt động."
Vì vậy, chắc chắn có một số ưu điểm ở đây, nhưng chúng có thể vượt trội hơn nhiều so với nhược điểm.
Khớp nối
Trong kịch bản này, tất cả các lớp như vậy được xây dựng từ một ConfigBlock
thể hiện cuối cùng có các phụ thuộc của chúng trông như thế này:

Điều này có thể trở thành PITA, ví dụ, nếu bạn muốn kiểm tra đơn vị Class2
trong sơ đồ này một cách cô lập. Bạn có thể phải mô phỏng bề ngoài các ConfigBlock
đầu vào khác nhau có chứa các trường có liên quan quan Class2
tâm để có thể kiểm tra nó trong nhiều điều kiện khác nhau.
Trong bất kỳ bối cảnh mới nào (dù là thử nghiệm đơn vị hay toàn bộ dự án mới), bất kỳ lớp nào như vậy đều có thể trở thành gánh nặng cho (tái) sử dụng, vì cuối cùng chúng ta phải luôn mang ConfigBlock
theo khi đi xe, và thiết lập nó phù hợp.
Khả năng sử dụng lại / Khả năng triển khai / Khả năng kiểm tra
Thay vào đó, nếu bạn thiết kế các giao diện này một cách thích hợp, chúng ta có thể tách chúng ra ConfigBlock
và kết thúc bằng một cái gì đó như thế này:

Nếu bạn chú ý trong sơ đồ trên, tất cả các lớp sẽ trở nên độc lập (các khớp nối hướng tâm / hướng ra của chúng giảm đi 1).
Điều này dẫn đến các lớp độc lập hơn (ít nhất là độc lập ConfigBlock
), có thể dễ dàng hơn rất nhiều để sử dụng / kiểm tra lại trong các kịch bản / dự án mới.
Bây giờ Client
mã này kết thúc là mã phải phụ thuộc vào mọi thứ và lắp ráp tất cả lại với nhau. Gánh nặng cuối cùng được chuyển đến mã máy khách này để đọc các trường thích hợp từ a ConfigBlock
và chuyển chúng vào các lớp thích hợp làm tham số. Tuy nhiên, mã khách hàng như vậy thường được thiết kế hẹp cho một bối cảnh cụ thể và tiềm năng tái sử dụng của nó thường sẽ là zilch hoặc đóng lại (dù sao đó có thể là main
chức năng điểm vào ứng dụng của bạn hoặc đại loại như thế).
Vì vậy, từ quan điểm tái sử dụng và thử nghiệm, nó có thể giúp làm cho các lớp này độc lập hơn. Từ quan điểm giao diện cho những người sử dụng các lớp của bạn, nó cũng có thể giúp nêu rõ các tham số họ cần thay vì chỉ một khối lớn ConfigBlock
mô hình toàn bộ vũ trụ của các trường dữ liệu cần thiết cho mọi thứ.
Phần kết luận
Nói chung, loại thiết kế hướng lớp này phụ thuộc vào một khối nguyên khối có mọi thứ cần thiết có xu hướng có các loại đặc điểm này. Khả năng ứng dụng, khả năng triển khai, tái sử dụng, khả năng kiểm tra của họ, vv có thể bị suy giảm đáng kể do đó. Tuy nhiên, họ có thể đơn giản hóa thiết kế giao diện nếu chúng ta thử một vòng quay tích cực trên nó. Tùy thuộc vào bạn để đo lường những ưu và nhược điểm đó và quyết định xem sự đánh đổi có xứng đáng hay không. Thông thường, sẽ an toàn hơn nhiều khi nhầm lẫn với kiểu thiết kế này khi bạn chọn anh đào từ một khối nguyên khối trong các lớp thường được dự định để mô hình hóa một thiết kế chung hơn và có thể áp dụng rộng rãi.
Cuối cùng nhưng không kém phần quan trọng:
extern CodingBlock MyCodingBlock;
... điều này thậm chí còn tệ hơn (sai lệch hơn?) Về các đặc điểm được mô tả ở trên so với phương pháp tiêm phụ thuộc, vì nó kết thúc việc ghép các lớp của bạn không chỉ với ConfigBlocks
, mà trực tiếp với một thể hiện cụ thể của nó. Điều đó càng làm giảm khả năng ứng dụng / khả năng triển khai / kiểm tra.
Lời khuyên chung của tôi sẽ sai về phía thiết kế giao diện không phụ thuộc vào các loại nguyên khối này để cung cấp các tham số của chúng, ít nhất là cho các lớp áp dụng chung nhất mà bạn thiết kế. Và tránh cách tiếp cận toàn cầu mà không cần tiêm phụ thuộc nếu bạn có thể trừ khi bạn thực sự có một lý do rất mạnh mẽ và tự tin để không tránh nó.