Giả sử có một lớp trừu tượng với một hàm tạo gọi một phương thức trừu tượng được bảo vệ chưa được lớp con thực hiện. Đây có phải là một ý tưởng tốt hay xấu? Tại sao?OOP tốt hay xấu?
Trả lời
Đây là một ý tưởng tồi.
Về cơ bản, bạn đang tạo ra sự đảo ngược kiểm soát trong một hàm tạo. Phương thức trong lớp cơ sở đang được gọi được gọi trước khi dữ liệu lớp cơ sở được khởi tạo (trong hầu hết các ngôn ngữ), cũng rất nguy hiểm. Nó có thể dễ dàng dẫn đến hành vi không xác định.
Hãy nhớ rằng, trong hầu hết các ngôn ngữ, khi bạn xây dựng một lớp, tất cả các cấu trúc lớp cơ sở sẽ chạy trước tiên. Vì vậy, nếu bạn có một cái gì đó như: MyClass() : MyBaseClass() {}
, thông thường, hàm xây dựng của MyBaseClass
chạy toàn bộ, thìMyClass
của hàm tạo thi hành. Tuy nhiên, bằng cách sử dụng một phương thức ảo trong lớp cơ sở, bạn đang gọi một phương thức cá thể trong MyClass
trước khi nó được khởi tạo hoàn toàn - điều này có thể rất nguy hiểm.
Điểm tốt. Cảm ơn sự hiểu biết của bạn. – StackOverflowNewbie
Đây là một ý tưởng tồi, bởi vì trong hầu hết các ngôn ngữ OOP, đứa trẻ được khởi tạo sau khi cha mẹ được khởi tạo. Nếu chức năng trừu tượng được thực hiện trong đứa trẻ, sau đó nó có thể hoạt động trên dữ liệu trong các con theo giả định không chính xác rằng nó đã được khởi tạo, mà không phải là trường hợp trong xây dựng cha mẹ.
Ví dụ:
class Base {
public:
Base() { virtualInit(); }
virtual ~Base() {}
protected:
virtual void virtualInit() {}
};
class Derived : public Base {
public:
Derived() : ptr_(new SomeObject) {}
virtual ~Derived() {}
protected:
virtual void virtualInit() {
// dereference ptr_
}
private:
scoped_ptr<SomeObject> ptr_;
};
Trong ví dụ trên, Base::Base()
được thực hiện trước khi Derived::Derived()
, đó là trách nhiệm khởi ptr_
. Do đó, khi virtualInit()
được gọi là từ Base::Base()
nó dereferences một con trỏ uninitialized, dẫn đến tất cả các loại rắc rối. Đây là lý do tại sao ctors và dtors chỉ nên gọi các hàm không phải ảo (trong C++), các hàm cuối cùng (trong Java), hoặc tương đương với ngôn ngữ cụ thể.
Tôi không thể thấy lý do tại sao bạn muốn làm điều này, hãy để một mình hội đủ điều kiện. Có vẻ như bạn đang cố tiêm một số chức năng vào đối tượng. Tại sao bạn không chỉ quá tải constructor hoặc tạo một thuộc tính có thể được thiết lập để bạn có thể inject các chức năng thông qua composition hoặc thậm chí tạo constructor với tham số là đối tượng IOC.
Khi người khác đã đăng, điều đó phụ thuộc vào ngữ cảnh mà trong đó bạn đang cố giải quyết một vấn đề cụ thể. Sự phù hợp tự nhiên sẽ tuân thủ một giao diện, phát triển một lớp trừu tượng và quá tải các hàm tạo trong mỗi lần thực hiện. Nếu không có thêm thông tin, tôi chỉ có thể bình luận về những gì đã được đăng trong câu hỏi của bạn.
Thiết kế này bạn không thể coi là tốt hay xấu. Chỉ đơn giản là từ thực tế rằng nó có thể là cách duy nhất bạn có thể đạt được những gì bạn đang cố gắng làm.
Cảm ơn bạn đã nhập. Tôi không thực sự cố gắng giải quyết một vấn đề cụ thể. Chỉ cần hỏi ý kiến cho một giải pháp thiết kế có thể. – StackOverflowNewbie
giao diện tốt hơn như thế nào? Điều gì xảy ra nếu tôi cần một lớp học chung cho tất cả các lớp học để kế thừa? Các lớp phổ biến chính nó không nên được instantiated trực tiếp, nhưng có chứa một số phương pháp và tài sản mà các lớp hậu duệ cần? Bạn sẽ không cần một lớp trừu tượng để bạn có thể hưởng lợi từ thừa kế? – StackOverflowNewbie
Sở thích cá nhân, tôi luôn luôn làm thành phần thừa kế trong thiết kế chương trình của mình. Tôi thấy các giải pháp mạnh mẽ hơn. Tôi sẽ xem xét vấn đề bằng cách sử dụng phương pháp CRC và làm việc ra các tương tác nhiều hơn thừa kế. Một đối tượng có trách nhiệm và nên rất giỏi. Nó cũng có thể được thay thế bằng một loại tương tự khác. Do đó, tôi sẽ xem xét các hành vi và thiết kế xung quanh những hành vi này trước tiên. Không nói rằng tôi sẽ không làm thừa kế, nhưng nó không phải cái gì tôi nghĩ từ lúc khởi phát, nó thường xảy ra xuống dòng khi tôi tái yếu tố. – WeNeedAnswers
Chỉ sau đó là một ý tưởng TỐT, IFF bạn có thể quản lý nó để không bắn vào chân của bạn. Nhưng dù sao, OOP luôn dễ bị thiết kế xấu; vì vậy nếu ngôn ngữ của bạn cho phép các mô hình khác hơn OOP, để sử dụng OOP trong trường hợp này chắc chắn là một sự lựa chọn BAD.
Ít nhất trong C++, lớp con xác định trình tự tất cả các khởi tạo được tạo; đó là khởi tạo của tất cả các biến thành viên và các hàm tạo của tất cả các lớp cha. Điều này đã được xem xét!
Hoặc, bạn có thể cung cấp cho hàm tạo (như tham số) một con trỏ tới một hàm cụ thể (tôi thích các hàm tĩnh), thay vì gọi hàm trừu tượng thành viên.Đây có thể là một giải pháp thanh lịch và lành mạnh hơn nhiều; và đây là giải pháp thông thường trong (có thể là tất cả) ngôn ngữ không phải là OOP. (trong java: Một con trỏ trỏ tới một hàm hoặc một danh sách các hàm là mẫu thiết kế của một giao diện và ngược lại.)
- 1. ASP MVC HTML Helpers - Tốt hay Xấu?
- 2. Có đặc điểm tốt hay xấu?
- 3. Đối tượng khỏa thân. Tốt hay xấu
- 4. Cơ sở dữ liệu Upserts - Thực hành tốt hay xấu?
- 5. Quá tải phương thức - thiết kế tốt hay xấu?
- 6. Tắt Chế độ tương thích IE8, Tốt hay Xấu?
- 7. Toán tử bậc ba: thực hành tốt hay xấu?
- 8. Một BaseModel trong PHP MVC, tốt hay xấu?
- 9. O/R Người lập bản đồ - Tốt hay xấu
- 10. WCF Tự lưu trữ trên máy khách? Tốt hay xấu
- 11. Chiến lược kết nối hồ bơi: Tốt, Xấu hay Xấu xí?
- 12. DateTimeZone lỗi: Unknown hay xấu múi giờ
- 13. Nguồn đào tạo tốt cho OOP PHP, Bất kỳ ai?
- 14. "Singleton" nhà máy, ok hay xấu?
- 15. Nén Memcache - tốt/xấu?
- 16. Tài nguyên OOP JavaScript tốt là gì?
- 17. Thư viện Lua OOP tốt nhất
- 18. Ý tưởng tốt hay xấu để bao gồm các số trong tên bảng SQL?
- 19. Thực hiện hàng đợi C bằng cách sử dụng void * - thực hành tốt hay xấu?
- 20. Thực hành tốt hay xấu trong Python: nhập ở giữa tệp
- 21. Nhiều biểu mẫu có trường nhập liệu có cùng tên thuộc tính? Tốt hay xấu?
- 22. Ví dụ tốt hay xấu về sử dụng công nghệ Flash/Flex
- 23. ToString() ở đây tốt, xấu hay đơn giản là dư thừa?
- 24. Nhiều lớp DbContext cho một ứng dụng web duy nhất. Tốt hay xấu?
- 25. Mô phỏng các tham số hàm được đặt tên trong PHP, ý tưởng tốt hay xấu?
- 26. Thực hành tốt hay xấu cho Dialogs trong wpf với MVVM?
- 27. Có phải gói mới trong nhà xây dựng tốt hay xấu?
- 28. Phương pháp mở rộng - IsNull và IsNotNull, sử dụng tốt hay xấu?
- 29. Java - "Xoay" đối tượng trong một LinkedList - Là LinkedList.addLast (LinkedList.removeFirst()) Tốt hay xấu Lập trình?
- 30. Các loại PHP trước đối số chức năng, tốt hay xấu?
Có. các lớp trừu tượng là một ý tưởng tồi. – tidwall
Các lớp trừu tượng không phải là một ý tưởng tồi - chỉ có khả năng gọi các phương thức ảo từ bên trong một hàm tạo. Ý tưởng cũng xấu cho các lớp cụ thể - không chỉ trừu tượng;) –
@Reed, không, các lớp trừu tượng là một ý tưởng tồi (mặc dù vì các lý do khác). Thông thường, ủy nhiệm/tập hợp là một cơ chế tốt hơn, ít bị lỗi để tái sử dụng mã hơn là thừa kế. Giao tiếp thừa kế là tốt (tức là không thực hiện), nhưng thừa kế lớp là một ý tưởng khủng khiếp. –