Posts tagged with 'SOLID'
One of my core motivations for using AOP is that it can bring the single responsibility principle to places that would otherwise be difficult or impossible without AOP.
To review, here's the single responsibility principle in a nutshell:
A class should have one, and only one, reason to change.
Why is this a good principle? I think that the ObjectMentor white paper on SRP [PDF] sums it up very nicely, but basically if you have multiple concerns in a single class, those concerns become tangled together. This isn't a huge problem until you need to make a change (which never happens in software, right?). If I want to change responsibility A, I now have to involve the code for responsibilities A and B (and C and D, etc). All these responsibilities are coupled. If I make a change, I could break the class in multiple ways, affecting every one of the coupled concerns (unless I have a good suite of unit tests, which is unlikely if I have a very coupled set of concerns).
To avoid coupling, a good rule of thumb that I use is to describe what a class does in one sentence. If I have to use the word "and", then it's probably doing too much, and should be split into 2 or more classes.
Examples:
- PersonRepository: this class persists person objects to a database. Check! There's no "and", so this class is only doing one thing.
- BillPayService: this class submits transactions to the payment processor and stores payment history in an audit database. Bzzt! It's doing two things. Maybe I should consider a PaymentProcessorService and a PaymentHistoryRepository refactor.
- AccountController: this class routes the user to the appropriate account views (and logs any invalid request errors). I'll stop belaboring the point and leave this an an exercise to the reader.
I came across an abstract and slides (PDF) about using AOP to detect code smells. It got me thinking: is clean code and SOLID architecture itself a cross-cutting concern? Usually "good, maintainable code" isn't ever written down explicitly as a requirement (functional or otherwise); it's just sorta assumed that developers will write the best code they can. Obviously that doesn't always happen, and the customer probably won't know one way or the other until after release.
As a developer, sometimes it's hard for me to be objective when looking at my code and the choices that I've made. Pair programming is one way to help alleviate this: I can get instant feedback from another developer as I'm coding and making decisions. Test driven development also helps, by forcing me to write code that's easy to test (and therefore loosely coupled). Not every project or code base has the luxury of either of these things: maybe there's only 1 developer, or maybe it's a legacy code base. Whatever the reason, another approach to take is code analysis: code metrics like cyclomatic complexity and maintainability index. There's also heuristics, aka "code smells" that (not always, but usually) indicate that there might be a problem.
There are three code smells addressed by the Juliana Padilha's slides, none of which I've heard before:
- Divergent change: this sounds like the opposite of Single Responsibility. I.e. the class has more than one reason to change, and thus its responsibility is diverging.
- Shotgun surgery: I've not heard this term, but I've certainly seen it (and been guilty of it myself). Making a change requires touching a handful of different classes instead of just one or two.
- God class: I actually have heard of this, and if you consider classes with 300+ line Page_Load methods in ASP.NET to be God classes, then I've certainly seen it and done it.
The metrics that she uses to find these smells are not traditional metrics, but "concern-driven" metrics, meant to identify code "scattering" and "tangling" (i.e. the code that AOP is meant to help refactor), and includes:
- Concern Diffusion over Class (CDC)
- Concern Diffusion over Operation (CDO)
- Number Concerns per Class (NCC)
- Concern Diffusion over Lines of Code (CDLOC)
These metrics weren't defined in the slides, but I found them in another white paper from Columbia.
Do you agree with these concepts?
TDD is great, BDD is better. DDD is the way it should be done. SOLID principles should always be followed. Don't repeat yourself. Be agile. Follow the boy scout rule. Use an IoC tool and/or dependency injection. Don't reinvent the wheel. Always normalize your SQL tables. Use AOP to avoid boilerplate and clutter.
I do. And a lot of other people do too. But why? Because:
- ...it's been drilled into your head by peers and at software conferences?
- ...you have baggage from a previous job or hate your current job?
- ...you read about them all in a book like Clean Code, and assumed Uncle Bob knows what he's talking about?
Or have you actually researched and practiced each of these concepts and found them to be superior in many cases to the alternatives (which you've also researched and practiced)?
Well, for me, the answer is: all of the above. Except I don't hate my (current) job.
Yes, I just admitted that I've blindly subscribed to a lot of the tenets that you probably hold dear because of peer pressure and authority figures. This isn't necessarily a bad idea: authority figures and peer pressure can be useful constructs. But independent of your own healthy skepticism and critical thought, they can be dangerous too.
So before you run with any new acronym like BDD or AOP, do your research: see what your peers think, see what authority figures think, and finally use your own brain to put it all together.
Week #2 is coming to an end here at CrossCuttingConcerns, which means it's time for another link dump post.
- LIDNUG (Linked-in .NET user group) recently posted video of Gael Fraiteur at their user group meeting. This was recorded in November 2010, so it's a bit behind the times as far as PostSharp goes, but it's still an informative video.
- Here's a white paper comparing AOP to composition filters (CF). I've not heard of CF before this paper, but it seems that like AOP, CF aims to address the same limitations with cross-cutting concerns that AOP does. (PDF link)
- Taking the Single Responsibility Principle (SRP) seriously. A deep dive into SRP, and just what is a "responsibility" anyway?
- Another white paper, but this one is about an interesting use case of AOP. It's based on a project to "trace" an application: not in the traditional developer sense of tracing through the code, but rather tracing a user's actions as she uses the interface to a system. And then using that information for later analysis (perhaps a usability study?).
- A blog post from Kristijan Rebernišak about using AOP to check user permissions: he uses Google Guice with AOPAlliance.
- Chad England has started a blog post series on AOP with PostSharp.
Thanks for reading, and please leave a comment or use the contact link above if there's something you'd like to see covered here on CrossCuttingConcerns.com (or if you have something to say and want it published here).