Practical C# API example with Command and Abstract factory patterns — Part 1

Marek Balaz
4 min readOct 26, 2022

--

Design patterns are an important part of software development. They provide developers to maintain clean, easily readable, and extensible code design. Although each better company requires design patterns knowledge, many developers consider these patterns difficult to implement and refuse to learn them. They started to find tutorials on the Internet. However, they found only basic tutorials with theoretical cases without practical examples. I think this approach may be the main reason why developers consider design patterns difficult.

Therefore, I decided to create this tutorial, in which we will implement a simple and practical C# API example consisting of a combination of two design patterns — Command and Abstract factory.

Task

Create REST API in C# ASP .NET Core WEb API technology. API should be able to receive JSON message with parameters method and data (message example is below this block). Parameter method represents statistical function as average (avg), variance (var) or standard deviation (std). API applies the selected method to the second parameter data (array of numbers).

{
"method": "avg",
"data": [1.0, 2.7, 5.4, 3.3, 9.1]
}

Solution initialization

In practice, we shouldn’t write business logic code directly into API controller methods. If we split the business layer (business logic) from the presentation layer (in this case API controller), it will be simpler for us to write unit tests and extend the application by newly implemented code. Therefore, our C# solution will consist of two projects. Follow the next steps in order to initialize solution:

  • Step 1: Create a new project as ASP .NET Core Web Api with project name StatProjectAPI and solution name StatProject
  • Step 2: Remove WeatherForecast.cs and WeatherForecastController.cs files from StatProjectAPI
  • Step 3: Add new Class library project into solution with name StatProjectLib (right click on StatProject in Solution Explorer > Add > New project > Select Class Library)
  • Step 4: Remove Class1.cs from StatProjectLib
  • Step 5: Add StatProjectLib to StatProjectAPI (righ click on Dependencies in StatProjectAPI > Add project reference > Select StatProjectLib > click on OK button)
  • Step 6: Create folder Models in StatProjectAPI and SimpleCommand folder in Models
  • Step 7: Create folder Commands in StatProjectLib and create Simple folder in Commands
  • Step 8: Create folder Factories in StatProjectLib
Initialized solution (after 8 steps)

In this example, we will implement business logic into the Class library project. I choose the class library just for simplicity. However, if you work on complex solution, use a private NuGet package instead.

Command pattern

In the task specification, we need to implement three simple statistical functions — average, variance, and standard deviation. If you’re not familiar with the Command pattern, you will probably implement all of these functions in one (static) class. Of course, it is a simple and quick solution. However, developers should “think ahead”. In this case, you would have to implement a new method in the same class every time your client wants to add new statistical functions. As you probably know, a class with many methods is difficult to read and maintain.

The better solution is to implement each statistical function as a new class. So we are going to implement first class for average, second class for variant, and third class for standard deviation function. If the client wants to add a new function, we will only implement another (statistical) class. In the future, we may have hundreds of classes (one for each statistical function). However, each class would be implemented in a separate file. Therefore, the code of each class will be easy to maintain and read.

Create each file in this section in StatProjectLib/Commands/Simple/

Each class that implements statistical function will have the suffix “Command”. They should implement the same interface ISimpleCommand (in the future, we could have complex statistical functions e.g. to compare multiple number arrays). In our task, we need to apply selected statistical function on a number array. And what does a simple statistical function do? It computes statistical value (output) from number array (input). Therefore, our interface defines only one method Compute with double array as parameter (input) and return type double (output).

Class AverageCommand represents average statistical function. Class computes average in implemented method Compute. As you can see, we transformed method (statistical function) into a simple class.

Class VarianceCommand computes variance also in method Compute.

The last class is StandardDeviationCommand which computes standard deviation. As you probably know, the standard deviation is square root of variance. Therefore, it is easy to implement the class as a child of VarianceCommand and call Compute method of the parent.

Now, we have successfully implemented the Command pattern in which we transformed each statistical function into a new class that implements a common interface with the method Compute. Most Command pattern implementations prefer method name as Execute or Process. The name, return type and parameters depend on your problem.

Final class diagram

In complex solutions, Command classes may contain their own attributes or properties. You can also insert Command classes into the queue and perform methods later (e.g. asynchronous tasks).

In second part, we will implement Abstract factory pattern.

--

--

Marek Balaz

C# software developer and fan of programming techniques