简体   繁体   中英

Using Adapter Design Pattern

I was working on implementing an adapter design pattern to utilize the existing classes. My problem is, the classes works almost same, but have different names and less functionalities on another.

For example, each Work class and Homework class has one function that does the same, which is doWork() and doHomework() .
I can link these to doThis() in Task interface. But, Work class doesn't have done() function while Homework class has it. How would I take care of this? Just no implementation? Are there any better approach?

class Task {
public:
  virtual int doThis() = 0;
  virtual bool done() = 0;
};

class Work {
public:
  Work();
  int doWork();
};

class Homework {
public:
  Homework();
  int doHomework();
  bool done();
  bool isDone;
};

class WorkAdapter : public Task, private Work {
public:
  WorkAdapter();
  int doThis() {
    return doWork();
  }
  virtual bool done() {
    // Is this okay not to implment this?
  }
};

class HomeworkAdapter : public Task, private Homework {
public:
  HomeworkAdapter();
  int doThis() {
    return doWork();
  }
  virtual bool done() {
    return isDone;
  }
};

int main() {

  Task *homework = new HomeworkAdapter();
  Task *work = new WorkAdapter();

  homework->doThis();
  bool isHomeworkDone = homework->done();

  work->doThis();
  bool isWorkDone = work->done();  // This would never be called in my implementation...
}

The adapter implementation using multiple inheritance (public for the target, private for the adaptee) is a valid approach.

Just take care of the the return type of the function:

class HomeworkAdapter : public Task, private Homework {
public:
  HomeworkAdapter() {}
  int doThis() override {  // make sure you override target member
    return doWork();       // and return value as expected
  }
  bool done() override {
    return isDone;
  }
};

Hint: virtual doesn't need to be specified in the derived class. Instead it's worth to use override, just to avoid subtle issues in case of non matching parameter or return types.

When no feature is available for taking care of done() in the adaptee, you must emulate it. So its's not just about changing the name, but also ensuring similar behaviour:

class WorkAdapter : public Task, private Work {
  bool isdone;       // functionality to add
public:
  WorkAdapter() : isdone(false) {}
  int doThis() override {
    auto rc = doWork();
    isdone = true;    // once it's done, it's done ;-)
    return rc; 
  }
  bool done() override {
    return isdone;      // you must add this 
  }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM