Here's the thing - recently I put together some questions to use for interviewing, and one of the questions on there was simply what was "separation of concerns".
None of my team got that question right, although some of them are quite experienced, but all of them told me that this was a dated question that will only invite a textbook answer.
The point here is that a good design has good separation of concerns, and is coherent, but what does that mean? Simply put, a subsystem with a particular responsibility performs only that set of tasks, and no tasks for other subsystems. It's a little like the normalisation rules for databases, that the key must refer to all the data in a table.
This poses a couple of immediate questions, what happens when you have a Person subsystem, and want to get the addresses that that person resides at, without making a chatty set of calls?
There are a few approaches - if we're talking services, then the service call is very granular, and uses a DTO in effect to transport data from multiple sources. In the backend, the multiple source are nicely separate.
If the problem is considered from the backend, the Address subsystem would have to be injected into the Person subsystem, and vice versa. In this way you are delegating responsibility to the correct subsystem, however, this could lead to many calls to the database. Do we care? Well, we might do if the data really does have to be realtime, which is wouldn't in the given example above.
The final implementation would be to implement functionality (a PersonAddress nested subsystem within Person subsystem) or an AddressPerson nested within the Address subsystem. These would have a very different focus, or context, but the code is quite likely to be repeated in both. I guess that final point is similar again to the database example, in that generally you should start with 5th normal form, then work backwards to compromise redundancy against speed. Same with coherence, but it is "separation of concerns" versus maintainability.
Friday, July 10, 2009
Separation of Concerns
Posted by
Martin Platt
at
10:12 PM
0
comments
Labels: "separation of concerns", architecture, coherent, coupling, SOA
Decoupled design
Okay, so the question got asked on the Microsoft Forums about what was most appropriate, an interface, or an abstract class, so I thought that I'd bring that discussion over here for further discussion.
My response was to decouple, you would definitely use an Interface.
I was responded to with the question, but doesn't Inversion of Control containers now take care of abstraction, of de-coupling. I have to agree that it quite probably does.
That got me thinking, if you did use inversion of control, and always used abstract classes with no implementation, you would effectively have an interface. So why not use abstract classes everywhere? For me, it all comes down to clarity - the naming of an interface means that it is easy to understand it's function. An abstract class, on the other hand could be something ranging from effectively the interfacing class as described above, to something with lots of references to other abstract classes.
This is where I stand firm - my definition would be correct, if only to prevent that very thing from happening. When the implementation is part of a big team, those sorts of things can easily creep in, and before you know it, that beautiful, loosely coupled architecture is now reduced to a monolith.
So my advice here is always use interfaces, if you need an abstract class, create one, but only ever reference it using the interface. This bit here is another place where it is nice to have an interface - what if the base implementation changes? You can still create another base implementation class, and so long as the contract is unchanging, only that need change.
Coupling of code is all about the coupling of implementation from one to another - the very thing you have to avoid with SOA implementations and the like. The service call must be completely encapsulated.
Posted by
Martin Platt
at
9:49 PM
0
comments
Labels: abstract class, Decoupled, Interface, SOA
Monday, November 5, 2007
Service designs... People seem to have the wrong idea...
I hear a lot of people talk about web services like they're something special. What I don't understand is why people think that. All that they are is an available transport to allow multiple platforms to talk to the backend.
The web service code shouldn't be in the web service, but should be calling into some sort of factory, or broker to get it to do all the work.
We should really view a web service as an interface only, so it's a different view, but a similar sort of concept to a web page, mobile page, windows application, or whatever.
Code sat behind forms, or services should be as minimalistic as possible, so that we can de-couple our implementations from the method that we use to move to that data around. There's no difference between this concept and the concept of an MVC or MVP implementation.
Architecting High-Performance, Reusable, Granular Services and SOA.
Sorry people, but I don't believe the above is really a good idea at all.
You cannot write granular services that can perform well, in general. It's a shame that the selling point of SOA has often been this concept of re-usability... It is not! It is availability. You can access the service from many platforms, or that's the idea at least. The more technology specific the extensions you add to a service, the less you leverage the true power of SOA.
Managers particularly get to hear of SOA, and think of it as a great concept that will cut costs, save money and time, and generally be the answer to their prayers. Whilst it may be the latter, the other parts rely on an understanding of the technology. Writing services and expecting them to perform well, and be re-usable isn't going to happen, because in general you want your services to be quite specific to the problem that they address, to make them perform well.
Obviously if performance isn't a consideration, you'd probably be able to get away with granular services, but not for long! How many systems have you seen that started off as a few macros running on a users desktop application, and then becoming the company software platform, and having to attempt upscaling the solution?! What I'm saying is, if you're writing services, then that of itself should mean that the problem domain is complicated enough to justify the effort. don't do it, don't come up with a bunch of services such something to get a bunch of person records, then get a bunch of address records for a given person. Then you're going to try to munge them together, right? Please tell me you're joking! The whole process is over-engineered and would require so many workarounds that it's just not funny! Although I did have a giggle myself...
It's a much better idea to look at what you need, and how fast that needs to realistically perform, then come up with a solution that fits that requirement.
Generally speaking, distributed architecture means that you should be calling the backend only once if possible, to get better performance. If you're combining and consolidating services in the backend, you're introducing overhead and complexity that really isn't needed.
Can I get an Amen?!
Posted by
Martin Platt
at
4:13 PM
0
comments
Labels: architecture, granular, reusable, service, SOA