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

查看:125
本文介绍了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 :: cout<<< ...< 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写道:关于非虚拟界面的好文章,我建议您退房。

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

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

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