Posts tagged with 'c'
AOP is best used for cross-cutting concerns, which are often non-functional requirements. But what's the difference between functional requirements and non-functional requirements?
A functional requirement is a requirement about what an application should do. This is manifested in a form that the user can easily observe. Business rules, UI logic, etc.
A non-functional requirement is a requirement about how an application should work. This is stuff that a user typically doesn't see (and probably doesn't care about). Logging, caching, threading, etc.
So here's a quick exercise for you:
Which of these are functional and which are non-functional? Why?
- Addresses should be US-only, ZIP Codes must be five digits
- Every method call should log its own name and arguments to a text file.
- When returning a list of Customers, only Customers the current user is authorized to see should be returned.
- When submitting a new Customer, it must be put in a pending queue for approval by an administrator.
I'll post my answers in a later post, but feel free to leave your answers in a comment.
Maybe this series will turn into an Every-Other-Weekly Concerns?
- The Ruby Rogues podcast discussed AOP in a recent episode (episode 46). It's a good idea to listen to the whole podcast for context, but they don't really start discussing AOP directly until about 28 minutes in.
- The proxy/decorator pattern gives some of the same benefits that AOP can give you. Derick Bailey blogged about using proxies and decorators in JavaScript.
- A couple of white papers for you:
- FeatureC++ and AOP - What's feature-oriented programming?
- AOP is Quantification and Obliviousness - "obliviousness" often has a negative connotation, but I believe AOP in a team setting on a properly architected application can free up developers to concentrate on adding business value without having function requirements slowing them down
That's it for this week. Have a great weekend.
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.
In a previous terminology post on "advice", I pluralized advice to "advices" without even thinking about it.
Alexey Berezkin asks what the plural of "advice" actually should be, since "advices" isn't actually a valid English word. My answer is that "advices" is okay in the context of aspect-oriented programming, since it's basically jargon at that point.
Probably most correct would be "advice classes" or "advice instances", depending on the context. Advice classes are what I write using PostSharp, and advice instances are what get instantiated by the code that PostSharp's post compiler weaves into the rest of the code. "Advices" is sort of an overarching piece of jargon that covers both.
This is the last post of a series of posts about using ASP.NET's ActionFilter.
The last method that you can override in an ActionFilter is OnResultExecute, which runs after the result of a controller action has been executed.
An argument of type ResultExecutedContext gets passed in to OnResultExecute. It's not wildly different from ResultExecutingContext, except that instead of a "Cancel" member, you get a "Canceled" member, which just tells you after the fact if the action was cancelled or not. You can still access HttpContext, the Controller object, the Result, the RouteData, etc.
I can't really create another kitchen sink view like I could with the previous blog posts, because the ActionResult (usually a ViewResult) has already been executed. (I could still write to the Http Response, but that would be a little tedious).
Since OnResultExecuted can't output to the view, it's somewhat limited in its general usefulness. Logging, of course, can still be done here. Last minute changes to the HttpResponse might be a good use of this filter. You can still handle some exceptions, though using a HandleErrorAttribute filter might be a better idea for that.