在C#/ C非虚拟接口设计模式++ [英] Non-virtual interface design pattern in C#/C++

查看:136
本文介绍了在C#/ C非虚拟接口设计模式++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当设计一个界面,有人推荐使用非虚拟接口模式。有人可以简要地说明一下这种模式的好处是?

When designing an interface, someone recommended to use the non-virtual interface pattern. Can someone briefly outline what the benefits of this pattern are?

推荐答案

非虚接口模式的本质是,你必须私有虚拟的功能,这是由公开非虚函数(非虚拟接口)调用。

The essence of the non-virtual interface pattern is that you have private virtual functions, which are called by public non-virtual functions (the non-virtual interface).

这样做的好处是,该基类有超过它的行为更多的控制会比如果派生类能够覆盖其界面的任何部分。换句话说,基类(接口),可以提供关于它提供的功能更多的保证。

The advantage of this is that the base class has more control over its behaviour than it would if derived classes were able to override any part of its interface. In other words, the base class (the interface) can provide more guarantees about the functionality it provides.

举一个简单的例子,考虑好老的动物类与一对夫妇典型的派生类:

As a simple example, consider the good old animal class with a couple of typical derived classes:

class Animal
{
public:
    virtual void speak() const = 0;
};

class Dog : public Animal
{
public:
    void speak() const { std::cout << "Woof!" << std::endl; }
};

class Cat : public Animal
{
public:
    void speak() const { std::cout << "Meow!" << std::endl; }
};

这将使用我们已经习惯了平时的公众虚拟接口,但它有几个问题

This uses the usual public virtual interface that we're used to, but it has a couple of problems:


  1. 每个派生动物重复的代码 - 唯一改变的部分是字符串,但每个派生类需要全的std ::法院LT&;< ...<<的std :: ENDL; 样板代码

  2. 的基类不能做出什么说话()一样。派生类可能会忘记新的生产线,或者把它写入 CERR 或就此任何事情。

  1. Each derived animal is repeating code -- the only part that changes is the string, yet each derived class needs the whole std::cout << ... << std::endl; boilerplate code.
  2. The base class can't make guarantees about what speak() does. A derived class may forget the new line, or write it to cerr or anything for that matter.

要解决这个问题,你可以使用由一个私有的虚拟功能,允许多态行为辅以非虚接口:

To fix this, you can use a non-virtual interface that is supplemented by a private virtual function that allows polymorphic behaviour:

class Animal
{
public:
   void speak() const { std::cout << getSound() << std::endl; }
private:
   virtual std::string getSound() const = 0;
};

class Dog : public Animal
{
private:
   std::string getSound() const { return "Woof!"; }
};

class Cat : public Animal
{
private:
   std::string getSound() const { return "Meow!"; }
};

现在的基类可以保证它会写出到的std :: COUT ,并用新行结束。这也使得维护更加容易为派生类不需要重复的代码。

Now the base class can guarantee that it will write out to std::cout and end with a new line. It also makes maintenance easier as derived classes don't need to repeat that code.

香草萨特写的非虚拟接口一个很好的文章的,我会建议您检查出来。

Herb Sutter wrote a good article on non-virtual interfaces that I would recommend checking out.

这篇关于在C#/ C非虚拟接口设计模式++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆