Single Responsibility Principle

The single responsibility is very simple:

A class should have only one reason to change.

Robert C. Martin, SRP - The single responsibility principle

As an example let’s look at a sensor class, which should report it’s status and readings into a text file:

The class sensor has multiple responsibilities: it represents the sensor with it’s data, knows how an export file content should look like and how  to export it to the filesystem.

This is clearly a violation of the single responsiblity principle. Continue reading “Single Responsibility Principle”

Open-Closed Principle

Your company sells temperature sensors and software for it for many years. For the last 5 years there we produced only indoor sensors.
Yesterday your boss came around and told you, that you’ll now sell also outdoor sensors.
There is a class that feeds the gui with the average temperature of multiple sensors. You’re assigned the extend the average temperature class, which look quite messy after your change:

Before your change it simply took a List<IndoorTemperatureSensor> and it had only one for loop. But look at this – feels like we’re missing something….. Continue reading “Open-Closed Principle”

C# features: null coalesce & conditional operator

In C# we have nullable types and references which can be null. When we access them in a null state, a NullReferenceException is flying towards us.

There are cases, when the null object pattern may reduce null checks, but there still remain many places in your code where you have to implement them.

Let’s have a look at two C# features for null checking. Continue reading “C# features: null coalesce & conditional operator”

C# features: auto-implemented properties

Properties in C# are used to hide implementation details to the outside. Fields (variables) should normally not be exposed (public).

It’s recommended to use properties instead, wich have get and set “accessors”. From the outside the properties are accessed like fields, but the compiler generates hidden methods.

man_vs_auto

Continue reading “C# features: auto-implemented properties”

C# features: async/await – asynchronous programming

Since today must systems have multiple processor or cores, slow or blocking applications are less accepted than ever.
On the other hand applications have to handle multiple slow interfaces (network, filesystem, database, http, …), which don’t respond as fast as we would like to.

Over the years this became a challenge in development, working with multiple threads and the GUI in parallel isn’t that easy.

Since C# 5 the async and await keywords are available, which abstract this complex problem.
You call a method which has the async keyword in it’s definition. The call returns immediately, you can alter the GUI or do other stuff in parallel. At the point when you finally need the results, you use the await keyword.

Continue reading “C# features: async/await – asynchronous programming”

Interface Segregation Principle

The ISP was “invented” by Robert C. Martin while consulting for Xerox: “The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use.”*

I’ll explain this with an example, let’s assume we have an Interface SensorDevice that provides a lot of functions:

So what’s the problem with fat interfaces like in the example coding?

If clients use interface with methods they don’t need, they know details that they don’t care about.
In the sensor device example you will have code that controls maybe hundreds of different sensors and on the other hand there’ll be code that reads and handles the readings.
Device State, control and reading methods are tightly coupled togehter. If there’s a change in a method signature for example, all “clients” are eventually affected by the change – which is unnecessary.

Applying the interface segregation principle

To understand the ISP you must understand the difference between the (class-)interface and the object interface. Depending on the language a class can inherit from one or more classes and implement multiple interfaces

An object that implements multiple interfaces exposes all methods. But you also can access the object with the interface it implement, like IDisposable.
This allows a very specific access to a subset of the object interface, so that it can be treated in different ways without caring about its details.

Especially on higher levels of abstraction you will have objects with many methods, but you can group them using interfaces:

Class diagram - interface segregation principle

Now you can access the different methods by client-concern using the interfaces:

Console-Output
06.03.2016 07:17:37 ConsoleLogFakeSensor: enable()
06.03.2016 07:17:37 ConsoleLogFakeSensor: isEnabledSince()
06.03.2016 07:17:37 ConsoleLogFakeSensor: disable()
06.03.2016 07:17:37 ConsoleLogFakeSensor: powerOff()
Press any key to continue…

This will also be very handy if you want to disable dozens of different devices of different types using the generic interface “DeviceState” – without knowing which type of Device it is.

The example project is in this GitHub repository.

Conclusion

Splitting fat interfaces by client concerns is a powerful tool to build cohesive interfaces. Due to the reduced dependencies the scope of changes is minimised and the loose coupling will payoff in the long term when it comes to extending and maintaining the project. Smaller specific interfaces may also help to communication your intentions.

Sources

Dependency Inversion Principle

The dependency inversion principle states:

  • “High level modules should not depend upon low level modules. Both should depend upon abstractions.”
  • “Abstractions should not depend upon details. Details should depend upon abstractions.”

See Principles of Object Oriented Class Design by Robert C. Martin (2000) for further details.

An example Application
The application sends e-mail notifications to users. The message text is different for regular and premium users.
The “BL” sub-package contains the business logic, it knows how to generate the email (address, subject and message) and how to call the SMTP client. Continue reading “Dependency Inversion Principle”