Trong C++, tôi thường sử dụng các đối tượng kiểu RAII để làm cho mã đáng tin cậy hơn và phân bổ chúng trên stack để làm cho mã hiệu suất hơn (và để tránh bad_alloc).Ngăn xếp các đối tượng RAII và nguyên tắc DI
Nhưng việc tạo đối tượng lớp bê tông trên ngăn xếp vi phạm nguyên tắc đảo ngược phụ thuộc (DI) và ngăn không cho nhại đối tượng này.
Xét đoạn mã sau:
struct IInputStream
{
virtual vector<BYTE> read(size_t n) = 0;
};
class Connection : public IInputStream
{
public:
Connection(string address);
virtual vector<BYTE> read(size_t n) override;
};
struct IBar
{
virtual void process(IInputStream& stream) = 0;
};
void Some::foo(string address, IBar& bar)
{
onBeforeConnectionCreated();
{
Connection conn(address);
onConnectionCreated();
bar.process(conn);
}
onConnectionClosed();
}
tôi có thể kiểm tra IBar::process
, nhưng tôi cũng muốn kiểm tra Some::foo
, mà không cần tạo đối tượng kết nối thực.
Chắc chắn tôi có thể sử dụng một nhà máy, nhưng nó sẽ làm phức tạp đáng kể mã và giới thiệu phân bổ đống.
Ngoài ra, tôi không muốn thêm phương thức Connection::open
, tôi thích xây dựng các đối tượng hoàn toàn được khởi tạo và đầy đủ chức năng.
Tôi sẽ thực hiện Connection
nhập thông số mẫu cho Some
(hoặc cho foo
nếu trích xuất dưới dạng hàm miễn phí), nhưng tôi không chắc chắn rằng đó là cách đúng (mẫu giống như ma thuật đen cho nhiều người) thích sử dụng đa hình động)
Mẫu không phải là ma thuật đen đối với lập trình C++ nhiều hoặc ít có năng lực, tôi không thấy lý do gì để tránh chúng.Ngoài ra tôi không nghĩ rằng phân bổ đống là * mà * đắt tiền (điều này, tất nhiên, phụ thuộc vào phần mềm bạn viết), vì vậy tôi thấy không có lý do để tránh nó hoặc (khi được sử dụng với con trỏ thông minh). –
@ Alex B: có loại lý do để tránh chúng, mặc dù tôi đồng ý rằng không phải vì chúng là "ma thuật đen". Đó là bởi vì nếu mọi thứ được tiêm thông qua các tham số mẫu, thì mọi thứ bạn viết là một mẫu, thư viện của bạn chỉ là tiêu đề và có thể khá cồng kềnh về mặt biên dịch hoặc phân phối. Mặc dù, tôi cho rằng với sự quan tâm bạn có thể đơn vị kiểm tra thư viện chỉ tiêu đề, sau đó xây dựng từ nó một TU chỉ chứa các instantiations mà ứng dụng cần. –
RAII và DI làm việc tuyệt vời với nhau, vì vậy tiêu đề là gây hiểu lầm, vấn đề của bạn là Phân bổ Stack so với DI. –