Single responsibility principle

This blog is the first of five blogs about the SOLID principles of object oriented programming (OOP). SOLID stands for:

  • Single responsibility principle
  • Open/closed principle
  • Liskov substitution principle
  • Interface segregation principle
  • Dependency inversion principle

These principles are first introduced by Robert C. Martin in the beginning of the 21st century. When you follow these principles, you will have a greater chance to deliver software that will be maintainable over a long period of time.

Example

As the title says, this blog is about the single responsibility principle. The goal of this principle is to write classes which have only one reason to change. Let’s take a part of code  (Python 3) that writes data from a database to an Excel workbook with the help of Openpyxl (the code is part of a not so well written program but try not too look at that).

ws2 = wb.create_sheet(title="W&V")
ws2['A1'].font = self.styb
ws2['A1'] = "Winst-en-Verliesrekening over " + str(year)
ws2.merge_cells('C3:D3')
ws2['C3'] = str(year)
ws2.merge_cells('E3:F3')
ws2['E3'] = str(year2)
ws2['C4'] = ws2['D4'] = ws2['E4'] = ws2['F4'] = "€"

In the code we make a worksheet called W&V. From there we create a font and write and merge cells.

This code can change the values on the worksheet without any problem, the variables make sure of that. But what happens when the final user of the created file want’s his data written to an PDF instead. Then you will find out that this code violates the single responsibility principle, because it does not only change the data in the report, it also defines that we save that data as an .xlsx file.

How can you prevent situations like this from happening

To prevent situations like this from happening you can create an abstract base class called Writer. For this class you create a child class that implements all the methods defined in the Writer parent class (for example: ExcelWriter or PDFWriter). When you start to write the code to write to Excel or PDF you instantiate and instance of this Writer class. This way the data is decoupled from the file type.

class Writer:
    __metaclass__ = ABCMeta
    def __init__(self):
        print("Writer")

class ExcelWriter(Writer):
    def __init__(self):
        Writer.__init__(self)
        print("ExcelWriter")

class PDFWriter(Writer):
    def __init__(self):
        Writer.__init__(self)
        print("PDFWriter")

When you are starting to build programs this will look like a lot of extra work, but eventually it will make it easier to make changes to your  program. Remember to use techniques like this one for (almost) every project, because you will want to be able to change the application fast if the requirements change.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s