Non-virtual interface design pattern in C#/C++

Non-virtual interface design pattern in C#/C++

The Non-virtual Interface (NVI) design pattern is a technique used to encapsulate the public interface of a class behind non-virtual member functions. This pattern is commonly used in C++ to achieve better control over derived class behavior while providing a stable public interface.

The main idea behind the NVI design pattern is to have a public non-virtual member function that serves as an interface to the class's behavior. This non-virtual member function then calls private or protected virtual member functions that provide the actual implementation of the behavior. By doing so, the class can ensure that the behavior is not modified or overridden by derived classes, while still allowing flexibility in modifying the behavior through the use of private or protected virtual functions.

Let's see how this pattern can be implemented in both C++ and C#:

C++ Implementation:

class Base {
public:
    // Public non-virtual interface function
    void performTask() {
        // ... Perform some common pre-processing logic ...

        // Call the private virtual function for the actual implementation
        doTask();

        // ... Perform some common post-processing logic ...
    }

    // Destructor (virtual to support polymorphism)
    virtual ~Base() {}

private:
    // Private virtual function for the actual implementation
    virtual void doTask() = 0;
};

class Derived : public Base {
private:
    // Override the private virtual function for the specific implementation
    void doTask() override {
        // ... Specific implementation for Derived ...
    }
};

In C++, the NVI pattern is particularly useful because it allows the base class to control the overall behavior by providing common pre-processing and post-processing steps while leaving the specific implementation details to derived classes.

C# Implementation:

In C#, since methods are non-virtual by default, you don't need to follow the NVI pattern explicitly. However, you can achieve a similar effect by following best practices in design and encapsulation.

public abstract class Base
{
    // Public non-virtual interface method
    public void PerformTask()
    {
        // ... Perform some common pre-processing logic ...

        // Call the protected virtual method for the actual implementation
        DoTask();

        // ... Perform some common post-processing logic ...
    }

    // Protected virtual method for the actual implementation
    protected virtual void DoTask()
    {
        // ... Common implementation ...
    }
}

public class Derived : Base
{
    // Override the protected virtual method for the specific implementation
    protected override void DoTask()
    {
        // ... Specific implementation for Derived ...
    }
}

In C#, methods are non-virtual by default, so you can achieve similar encapsulation by making the public method non-virtual and the specific implementation method (DoTask() in this example) protected and virtual.

Though the NVI pattern is more commonly used in C++, the concepts of separating the public interface from the implementation and allowing customization through protected virtual methods are applicable to both C++ and C#. By following these practices, you can achieve better control over the behavior of your classes and promote maintainability and flexibility in your code.

Examples

  1. "Non-virtual interface design pattern C#"

    • Description: Explore the Non-virtual Interface (NVI) design pattern in C# and understand how it provides a template for implementing a consistent public interface while maintaining flexibility in the implementation details.
    • Code:
      public abstract class MyBaseClass
      {
          // Public interface method using NVI pattern
          public void PublicMethod()
          {
              // Non-virtual call to private implementation method
              PrivateMethod();
          }
      
          // Private implementation method
          private void PrivateMethod()
          {
              // Implementation details
          }
      }
      
  2. "NVI design pattern benefits in C++"

    • Description: Learn about the advantages of using the Non-virtual Interface (NVI) design pattern in C++ for encapsulating implementation details and providing a stable public interface.
    • Code:
      class MyBaseClass
      {
      public:
          // Public interface method using NVI pattern
          void PublicMethod()
          {
              // Non-virtual call to private implementation method
              PrivateMethod();
          }
      
      private:
          // Private implementation method
          void PrivateMethod()
          {
              // Implementation details
          }
      };
      
  3. "C# NVI pattern vs. abstract class"

    • Description: Compare the Non-virtual Interface (NVI) pattern with abstract classes in C# and understand when to use each approach for designing extensible and maintainable code.
    • Code:
      // Using abstract class for extensibility
      public abstract class MyBaseClass
      {
          // Abstract method for public interface
          public abstract void PublicMethod();
      }
      
  4. "Implementing NVI pattern in C++"

    • Description: Dive into the implementation details of applying the Non-virtual Interface (NVI) pattern in C++ and how it facilitates controlled access to the underlying behavior.
    • Code:
      class MyBaseClass
      {
      public:
          // Public interface method using NVI pattern
          void PublicMethod()
          {
              // Non-virtual call to private implementation method
              PrivateMethod();
          }
      
      private:
          // Private implementation method
          virtual void PrivateMethod()
          {
              // Implementation details
          }
      };
      
  5. "NVI pattern in C# with inheritance"

    • Description: Learn how the Non-virtual Interface (NVI) pattern can be applied in C# with inheritance, providing a structured way to extend and customize behavior.
    • Code:
      public class MyDerivedClass : MyBaseClass
      {
          // Overriding the private implementation method
          protected override void PrivateMethod()
          {
              // Custom implementation details for the derived class
          }
      }
      
  6. "C++ NVI pattern and template method"

    • Description: Understand the relationship between the Non-virtual Interface (NVI) pattern and the template method pattern in C++, and how they work together to define a skeleton of an algorithm.
    • Code:
      class MyBaseClass
      {
      public:
          // Public template method using NVI pattern
          void PublicMethod()
          {
              // Non-virtual call to private implementation method
              PrivateMethod();
          }
      
      private:
          // Private virtual implementation method
          virtual void PrivateMethod() = 0;
      };
      
  7. "NVI pattern in C# real-world example"

    • Description: Explore a real-world example of applying the Non-virtual Interface (NVI) pattern in C# to achieve separation of concerns and maintainability.
    • Code:
      public class DatabaseAccess
      {
          // NVI pattern for executing database operations
          public void ExecuteQuery(string query)
          {
              // Non-virtual call to private implementation method
              Execute(query);
          }
      
          // Private implementation method
          private void Execute(string query)
          {
              // Implementation details for executing the query
          }
      }
      
  8. "C++ NVI pattern and polymorphism"

    • Description: Understand how the Non-virtual Interface (NVI) pattern in C++ can be used in conjunction with polymorphism to create a flexible and extensible design.
    • Code:
      class MyBaseClass
      {
      public:
          // Public interface method using NVI pattern
          void PublicMethod()
          {
              // Non-virtual call to private implementation method
              PrivateMethod();
          }
      
      private:
          // Private virtual implementation method
          virtual void PrivateMethod()
          {
              // Implementation details
          }
      };
      
      class MyDerivedClass : public MyBaseClass
      {
      private:
          // Overriding the private implementation method
          void PrivateMethod() override
          {
              // Custom implementation details for the derived class
          }
      };
      
  9. "C# NVI pattern and unit testing"

    • Description: Explore how the Non-virtual Interface (NVI) pattern in C# can facilitate unit testing by allowing for easy substitution of implementations and controlled testing of the public interface.
    • Code:
      public class MyClass
      {
          // NVI pattern for public interface
          public void PerformOperation()
          {
              // Non-virtual call to private implementation method
              Perform();
          }
      
          // Private implementation method
          private void Perform()
          {
              // Implementation details
          }
      }
      
  10. "C++ NVI pattern and abstract base class"

    • Description: Explore the combination of the Non-virtual Interface (NVI) pattern and abstract base classes in C++ to create a clear separation between the public interface and implementation details.
    • Code:
      class MyBaseClass
      {
      public:
          // Public interface method using NVI pattern
          void PublicMethod()
          {
              // Non-virtual call to private implementation method
              PrivateMethod();
          }
      
      private:
          // Private virtual implementation method
          virtual void PrivateMethod() = 0;
      };
      

More Tags

kivy express-session uitableview angular2-injection percentile css-tables slider newrelic angularjs-interpolate image-formats

More C# Questions

More Electronics Circuits Calculators

More Genetics Calculators

More Various Measurements Units Calculators

More Biochemistry Calculators