【问题标题】:How can I avoid code repetition without losing the interfaces? [closed]如何在不丢失接口的情况下避免代码重复? [关闭]
【发布时间】:2014-08-17 00:37:00
【问题描述】:

以下是当前的代码设计(示例)。如何避免重复“methodParent()”的代码(在两个子类的实现中)而不丢失接口类?

//Interfaces
//=======================================================

class InterfaceParent() //Interface class 
{
   public:
     virtual void methodParent() = 0; 
}; 

class InterfaceChild1() : public InterfaceParent //Interface class 
{
    public:
     virtual void methodParent() = 0; 
     virtual void methodChild1() = 0; 
}; 
 class InterfaceChild2() : public InterfaceParent //Interface class 
{
    public:
    virtual void methodParent() = 0; 
    virtual void methodChild2() = 0;
}; 

// Concrete Classes
//=========================================================

 class Child1() : public InterfaceChild1  // Concrete Class
 {
    public:
     void methodParent() { cout << "PARENT_METHOD";  } 
     void methodChild1() { cout << "CHILD_1_METHOD"; } 
}; 
class Child2() : public InterfaceChild2 // Concrete Class
{
    public:
      void methodParent() { cout << "PARENT_METHOD";  } 
      void methodChild2() { cout << "CHILD_2_METHOD"; } 
}; 

提前感谢您的帮助!

桑托什

【问题讨论】:

  • Stack Overflow (Can anybody suggest..) 通常不允许主要基于意见的问题。此外,您的问题过于宽泛,您可能需要针对每个问题提出单独的问题线索。
  • 您已经提出“现在我的问题是:”但后面没有问题,只是一些陈述,其中一些没有意义(“接口类是必须的”)。
  • 创建实现methodParentclass ParentImpl : public InterfaceParent 并从该类派生孩子。您可以使用不同的实现创建多个。
  • @Santosh 仍然不正确。它们不是你的问题;你的问题是I want to know how can I avoid code repetition without loosing the interfaces?。另外,以后请不要忽略对高级用户(例如我自己)的建议编辑,因为您的问题仍然存在错误。
  • @zyboxinternational 我已经编辑了我的问题。我希望现在好多了。感谢您的所有帮助。

标签: c++ inheritance design-patterns


【解决方案1】:

如果你看到“methodParent()”,我需要在所有的孩子中实现它 类并且是代码的大量重复(以及维护 障碍)对我来说。

然后实现一个Abstract class 而不是你的接口。基本上它是一个接口(包含需要在子程序中实现的纯虚拟方法),但也包含一些“非纯”(已实现)虚拟方法,如果需要,可以在以后覆盖。

一般而言,抽象类用于定义实现和 旨在由具体类继承。 More here

我会这样做:

// abstract
class AParent() //Abstract class 
{
   public:
    virtual void methodParent() { ... }; // give a first implementation that can be overriden later on, only if needed
    virtual void methodeChild() = 0

}; 
//Now the concretes
class Child1() : public AParent 
{
    public:
     virtual void methodParent() { ... }; // Override (as an example, only if needed)
     virtual void methodChild() { ... }; //implement
}; 

class InterfaceChild() : public AParent 
{
    public:
    //void methodParent() // is inherited from AParent
    virtual void methodChild() { ... }; // implement
};

编辑如果您无法更改任何内容,请执行以下操作:

但是...它很丑:)

//Interfaces
//=======================================================

class InterfaceParent() //Interface class 
{
public:
 virtual void methodParent() = 0;    
}; 
class InterfaceChild1() : public InterfaceParent //Interface class 
{
public:
 virtual void methodParent() = 0; 
 virtual void methodChild1() = 0; 
}; 
class InterfaceChild2() : public InterfaceParent //Interface class 
{
public:
virtual void methodParent() = 0; 
virtual void methodChild2() = 0;
}; 

//Abstract
//=======================================================
//an abstract class to do the transition betwin interfacesChildXX and concrete classes
class AChildXX() : public InterfaceChildXX  // Concrete Class
{
public:
 virtual void methodParent() { cout << "PARENT_METHOD";  } //It's implemented here for all your childrens, but can still be overriden
 virtual void methodChildXX() = 0; 
};

// Concrete Classes
//=========================================================

class Child1() : public AChildXX  // Concrete Class
{
public:
 //void methodParent() { cout << "PARENT_METHOD";  } //It's inherited
 void methodChild1() { cout << "CHILD_1_METHOD"; } 
}; 
class Child2() : public AChildXX // Concrete Class
{
public:
  // void methodParent() { cout << "PARENT_METHOD";  } //It's inherited
  void methodChild2() { cout << "CHILD_2_METHOD"; } 
}; 

【讨论】:

  • 感谢您的回答。但我不能失去我的接口类。我已经相应地重新表述了我的问题。
  • 我没有看到任何变化,你能解释一下为什么你不能松开你的接口吗?
  • 我不能放弃接口,因为过去的项目被设计为处理两个不同的库实现,它们具有暴露给 GUI 代码和最终用户的通用接口。此外,所有接口都编译为单独的 dll,不能与两个库链接。我希望,我的描述很清楚。谢谢!
  • 我认为这是一个令人讨厌的设计缺陷,但 w/e。请确保您不能更改这部分代码,不要偷懒:)
  • 感谢您的宝贵时间。我只是想用“class AChildXX() : public InterfaceChildXX”这一行让自己清楚。在这里,InterfaceChildXX 表示所有接口子类(即 InterfaceChild*),对吗?顺便说一句:我和我的协调员谈过了,我不允许修改接口。你的解决方案不是那么难看!因为至少有一次有 12 个孩子和 20 种常用方法,我使用宏的方式要丑得多。
【解决方案2】:

这个问题有点奇怪,因为您通常会使用 virtual 来实际覆盖具有类特定行为的方法,但在您的情况下,methodParent() 总是相同的。

您可以添加实现的私有继承(参见有效的 C++,以明智地使用多重继承为例)

class InterfaceParentImpl() //Interface class 
{
public:
  void methodParent() { cout << "PARENT_METHOD";  }
}; 

class Child1 : public InterfaceChild1, private InterfaceParentImpl
{
  void methodParent() { InterfaceParentImpl::methodParent();  } 
}

还是要多写几遍,要改的话,只需要在一处做就可以了。

【讨论】:

  • 那我觉得用Abstract代替Interface更合适。这样,您不仅可以避免重新定义,而且还可以使您的代码可维护,因为它位于一个地方。另外,如果需要,您可以将 methodParent() 重新定义到子类中。
  • 感谢您的回答。但我不能失去我的接口类。我已经相应地重新表述了我的问题。
猜你喜欢
  • 2013-04-10
  • 2011-05-19
  • 1970-01-01
  • 2021-09-03
  • 2018-01-04
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 2017-01-25
相关资源
最近更新 更多