2012-04-26 30 views
15

Tôi đến từ nền C# và gần đây đã bắt đầu học C++. Một trong những điều tôi gặp phải là thành ngữ pimpl. Tôi đã thực hiện phát triển C# cho một số công ty lớn, nhưng chưa bao giờ bắt gặp nó.Thành ngữ pimpl có được sử dụng trong C# không?

Có thể điều này là sai, nhưng sự hiểu biết của tôi là nó cần thiết trong C++ vì việc sử dụng các tệp tiêu đề và không có tùy chọn lớp một phần.

Nhưng trong C#, chúng tôi sẽ xây dựng các ứng dụng sử dụng thư viện lớp mọi lúc. Nếu một cái gì đó thay đổi trong mã thư viện, chúng tôi sẽ biên dịch lại nó thành một dll và tham khảo dll mới trong dự án ứng dụng.

Tôi thực sự không hiểu tại sao cùng một điều không thể thực hiện được với C++. Pimpl trông giống như một hack xấu xí với tôi.

+4

Nó không phải là "cần thiết" trong C++, nó chỉ ở đó để tiết kiệm thời gian xây dựng (và trong một số trường hợp để duy trì tính tương thích nhị phân). Nếu C++ biên dịch/liên kết nhanh như C# biên dịch, tôi nghi ngờ bất cứ ai sẽ bận tâm. – ildjarn

+1

Bạn có thể tìm thấy bài đăng của Eric Lippert, [How Many Passes] (http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx), quan tâm. – Brian

Trả lời

26

Thành ngữ pimpl được sử dụng trong C#?

Điều đó tùy thuộc vào ý nghĩa của thành ngữ này.

Thành ngữ được đề cập về cơ bản là tách chi tiết triển khai của một loại thành một lớp và vùng bề mặt công khai thành lớp bao bọc chỉ đơn giản là giữ con trỏ đến lớp triển khai.

Điều này có hai lợi ích.

Đầu tiên, trong C++ nó có thể dẫn đến những cải tiến trong thời gian biên dịch vì người tiêu dùng khu vực bề mặt công cộng chỉ cần phân tích cú pháp tệp tiêu đề chứa khu vực bề mặt công cộng; họ không cần phân tích cú pháp tệp tiêu đề chứa chi tiết triển khai.

Thứ hai, điều này dẫn đến việc tách giao diện rất rõ ràng khỏi triển khai; việc thực hiện có thể thay đổi hoàn toàn mà không bao giờ có bất kỳ tác động nào đối với người tiêu dùng, bởi vì người tiêu dùng không bao giờ thấy chi tiết triển khai.

Lợi ích đầu tiên là không có vấn đề gì trong C#. Trình biên dịch C# nhanh. (Phần lớn tất nhiên vì ngôn ngữ được thiết kế để biên dịch nhanh.)

Lợi ích thứ hai là sử dụng đáng kể trong C#. Trong C#, cách thành ngữ để thực hiện mẫu này là tạo một lớp lồng nhau riêng thực hiện công việc "thực" và lớp công khai chỉ là mặt tiền với khu vực bề mặt công cộng. Một kỹ thuật tôi đặc biệt thích trong C# là tạo lớp public lớp cơ sở của lớp lồng nhau riêng, cung cấp cho lớp cơ sở một hàm tạo riêng để ngăn chặn phần mở rộng của bên thứ ba và sử dụng mẫu nhà máy để phân phát các cá thể của lớp lồng nhau riêng.

Tôi thực sự không hiểu tại sao điều tương tự không thể thực hiện được với C++.

Sau đó, tôi khuyến khích bạn cố gắng viết trình biên dịch C++. Bạn sẽ thành công trong việc tạo trình biên dịch C++ nhanh hơn nhiều, hoặc bạn sẽ tìm ra lý do tại sao cùng một điều không thể được thực hiện trong C++. Bạn được hưởng lợi một trong hai cách!

+2

Có lợi ích gì khi tạo một lớp lồng nhau riêng tư, trái ngược với bỏ qua lớp lồng nhau riêng tư nhưng vẫn sử dụng một hàm tạo riêng và phương thức factory? Bạn không thể ẩn chi tiết triển khai bằng cách chỉ đặt thành viên và trường có liên quan ở chế độ riêng tư? – Brian

+4

@Brian: Chắc chắn, nếu bạn có một lớp tầm thường hoàn toàn khép kín thì hãy làm tất cả trong một lớp học. Nhưng nếu bạn có một lớp cơ sở BankAccount và các lớp có nguồn gốc SavingsAccount và ChequingAccount, và sau đó nhiều lớp dẫn xuất từ ​​chúng ... và bạn muốn tất cả các lớp ngoại trừ lớp cơ sở là chi tiết thực hiện riêng của BankAccount? Bạn có thể làm cho họ nội bộ để lắp ráp, hoặc bạn có thể làm cho chúng riêng tư cho một loại. Sau này nhấn mạnh * với đồng nghiệp của bạn * rằng các lớp học này là chi tiết thực hiện riêng tư, không phải là trò chơi công bằng để tái sử dụng. –

+0

Vâng, có một số nỗ lực để nghĩ lại mô hình biên dịch cho ANSI C++ xem "mô-đun C++". Tuy nhiên, kết quả ít nhất là không chắc chắn. Nếu bạn là một nhà văn thư viện ANSI C++, bạn có thể làm sạch C++ hiện đại (và xuất bản mã nguồn), hoặc bạn thực hiện "C++" (có thể triển khai, có thể tái sử dụng, có thể bảo vệ) được ở ranh giới đầy "hack" chứ không phải ANSI còn nữa ... –

4

Vâng, đó là ("hack"). Nó được gây ra bởi một mô hình biên dịch dựa trên văn bản cho ANSI C++: trình biên dịch cần xem biểu diễn văn bản của mã để tạo ra một cái gì đó hữu ích. Không phải là nó phải như vậy, nhưng đó là cách nó được thực hiện ngày hôm nay.

1

Như Eric đã chỉ ra, thành ngữ pimpl có hai mục đích. Tôi sẽ chỉ thêm rằng mục đích thứ hai (tách giao diện và thực hiện) là một trong những mẫu thiết kế phần mềm nổi tiếng: Bridge (còn được gọi là Handle/Body tôi nghĩ). Bạn có thể đọc thêm về nó here

Các vấn đề liên quan