Tôi xin lỗi nếu câu hỏi của tôi quá dài và kỹ thuật nhưng tôi nghĩ rằng điều quan trọng đến nỗi người khác sẽ quan tâm đến nóMẫu khách truy cập chung chung hơn
Tôi đang tìm cách tách riêng một số phần mềm bên trong từ đại diện của họ trong C++
tôi có một lớp thông số chung chung (sau này được lưu trữ trong một container) có thể chứa bất kỳ loại giá trị với các boost :: bất kỳ lớp
tôi có một lớp cơ sở (khoảng) thuộc loại này (tất nhiên có nhiều nội dung hơn)
class Parameter
{
public:
Parameter()
template typename<T> T GetValue() const { return any_cast<T>(_value); }
template typename<T> void SetValue(const T& value) { _value = value; }
string GetValueAsString() const = 0;
void SetValueFromString(const string& str) const = 0;
private:
boost::any _value;
}
Có hai mức độ của các lớp thừa: Mức đầu tiên xác định loại và chuyển đổi sang/từ chuỗi (ví dụ ParameterInt hoặc ParameterString) Mức thứ hai định nghĩa hành vi và những người sáng tạo thực tế (ví dụ như bắt nguồn ParameterAnyInt và ParameterLimitedInt từ ParameterInt hoặc ParameterFilename từ GenericString)
tùy thuộc vào loại thực tôi muốn thêm chức năng bên ngoài hoặc các lớp học mà hoạt động này tùy thuộc vào loại thông số cụ thể mà không cần thêm các phương pháp ảo để các lớp cơ sở và không làm phôi lạ
Ví dụ: tôi sẽ muốn tạo ra các điều khiển gui thích hợp tùy thuộc vào loại tham số:
Widget* CreateWidget(const Parameter& p)
Tất nhiên tôi không thể hiểu loại Parameter thực từ này trừ khi tôi sử dụng RTTI hoặc thực hiện nó tự ngã của tôi (với enum và trường hợp chuyển đổi), nhưng đây không phải là giải pháp thiết kế OOP phù hợp, bạn biết đấy.
Giải pháp cổ điển là thiết kế mẫu của khách http://en.wikipedia.org/wiki/Visitor_pattern
Vấn đề với mô hình này là tôi phải biết trước đó có nguồn gốc loại sẽ được thực hiện, vì vậy (đặt lại với nhau những gì được viết trong wikipedia và mã của tôi) chúng tôi sẽ có loại:
struct Visitor
{
virtual void visit(ParameterLimitedInt& wheel) = 0;
virtual void visit(ParameterAnyInt& engine) = 0;
virtual void visit(ParameterFilename& body) = 0;
};
Có giải pháp nào để có được hành vi này theo bất kỳ cách nào khác mà không cần biết trước tất cả các loại cụ thể và không có khách truy cập ban đầu?
Edit:Dr. Pizza's solution seems the closest to what I was thinking, nhưng vấn đề là vẫn như nhau và phương pháp này là thực sự dựa vào dynamic_cast, rằng tôi đang cố gắng để tránh như một loại (ngay cả khi yếu) phương pháp RTTI
Có lẽ nó là tốt hơn để suy nghĩ đến một số giải pháp mà không cần trích dẫn mô hình khách truy cập và làm sạch tâm trí của chúng tôi. Mục đích chỉ là có chức năng như:
Widget* CreateWidget(const Parameter& p)
cư xử khác nhau cho mỗi tham số "bê tông" mà không làm mất thông tin về loại hình của nó
Thật đáng tiếc khi bài viết này dường như đã biến mất: nó đã khơi gợi sự quan tâm của tôi. Tôi cho rằng tám năm là vĩnh cửu trên Internet. – Nicole
@Nicole http://web.archive.org/web/20080517124442/http://www.objectmentor.com/resources/articles/acv.pdf – DrPizza
Cảm ơn bạn! Điều đó thật là tốt. – Nicole