Как я могу создать фабрику? Клиент может установить данные для методов, которые не определены в интерфейсе? (Проблема проектирования) - PullRequest
0 голосов
/ 03 октября 2010

У меня небольшая проблема с дизайном: у меня есть одна фабрика, которая будет создавать объекты того или иного типа. Но мое клиентское требование состоит в том, чтобы передавать (передавать) данные (с помощью методов установки) из внешнего мира в конкретный класс типа 1, а не для типа 2.

Если я помещу эти методы установки в интерфейс, они должны быть принудительно реализованы в обоих конкретных классах. Это НЕ мое требование. Я хочу передать данные 1 типа для 1-го типа (некоторые сеттеры) и хочу предоставить данные другого типа для другого типа (возможно, другие сеттеры, отличные от тех, которые содержатся в предыдущем типе.)

* 1005 например *

     class ISubjectExecutor
     {
         public:
        virtual void ISUBJECTEXECUTOR_EXPORTS_API Execute()=0;  
     };

     class COMExecutor: public ISubjectExecutor
     {
      public: 
     virtual void Execute()=0;
            void setCLSID();
            void setGuids();

     };
     class Win32Executor : public IWin32Executor
     {
       public:               
      virtual void Execute()=0;
            void setFilePath();

     }; 

Теперь здесь я не могу использовать указатель ISubjectExecutor (* pSubjectExecutor) для вызова методов установки Win32Executor или COMExecutor по моему выбору в любое время после получения указателя (ISubjectExecutor) с фабрики. Потому что все эти сеттеры никогда не существуют внутри интерфейса ISubjectExecutor, и вы не можете получить доступ ни к какому методу, который никогда не содержится внутри интерфейса и существует в конкретной реализации.

Как решить эту проблему с дизайном .?

С уважением Hassan

1 Ответ

0 голосов
/ 03 октября 2010

Вы можете определить один или несколько чистых виртуальных методов в вашем базовом классе, которые позволяют свойству быть установленным по тегу / значению (с соответствующими типами для значения и перечислением для тега).Затем производные классы реализуют код для подмножества значений тегов, которые они поддерживают, и, возможно, выдают какое-то «не поддерживаемое» исключение (или возвращают false?) При вызове для обработки свойства, которое они не поддерживают.Здесь я использую std :: string для представления значения, но вам может потребоваться другой тип или другие перегрузки.

 class ISubjectExecutor
 {
     public:
    virtual void ISUBJECTEXECUTOR_EXPORTS_API Execute()=0;  
    virtual void SetProperty(const Tag tag, const std::string& value) = 0;

   // full list of tags in all subclasses
   enum Tag {
     Guids,
     FilePath,
     CLSID
   };     
 };



 class COMExecutor: public ISubjectExecutor
 {
  public: 
    virtual void Execute()=0;

    // Valid tags are Guids, CLSID
    virtual void SetProperty(const Tag tag, const std::string& value);

 };
 class Win32Executor : public IWin32Executor
 {
   public:               
  virtual void Execute()=0;

    // Valid tags are FilePath
    virtual void SetProperty(const Tag tag, const std::string& value);
 }; 

Теперь можно вызывать SetProperty через указатель на ISubjectExecutor.

...