I’m in the midst of refactoring a project. I’ve recently read Clean Code, and want to heed some of the advice within, with particular interest in Single Responsibility Principle (SRP).
Currently, there’s a class called OrderProcessor in the context of a manufacturing product order system.
This class is currently performs the following routine every n minutes:
- check database for newly submitted + unprocessed orders (via a Data Layer class already, phew!)
- gather all the details of the orders
- mark them as in-process
-
iterate through each to:
- perform some integrity checking
- call a web service on a 3rd party system to place the order
- check status return value of the web service for success/fail
- email somebody if web service returns fail
- constantly log to a text file on each operation or possible fail point
I’ve started by breaking out this class into new classes like:
- OrderService – poor name. This is the one that wakes up every n minutes
- OrderGatherer – calls the DL to get the order from the database
- OrderIterator (? seems too forced or poorly named) –
- OrderPlacer – calls web service to place the order
- EmailSender
- Logger
I’m struggling to find good names for each class, and implementing SRP in a reasonable way.
How could this class be separated into new class with discrete responsibilities?
1
As a general rule I have 1 class for every object (often linked to a DB table) or process.
It can sometimes be difficult to define all your classes ahead of time, so I tend to create some bare-bones classes and start writing a rough version (often procedural) of what I want to do.
This process of actually seeing how your code hangs together enables me to start spotting patterns and links. I can then quickly change my skeleton classes quickly, effectively creating the design and workflow iteratively until I arrive at something I’m happy with.
I’d start with:
- OrderChecker – thread class that checks every n minutes
- OrderProcessor – gets new order from DB (using DAL) and processes each one – this is where the bulk of the work will take place, including making calls to EmailSender and Logger.
- OrderSender – Sends emails based on status of order (descended from generic email sender class)
- OrderLogger – Logs info based on results of order processing (descended from generic logger class?)
I find the key is to keep everything fairly “loose” (often quick-and-dirty) until you’re happy with your design and have accounted for all foreseeable issues/requirements.