Composite Architecture - The Open Close Principle as applied to system architecture
My post about tests got the expected response, and I think that Denis's comment is a good sample of the type of feedback that I got:
...you won't be able to ship periodically at sustainable costs and quality without relevant engineering practices like unit tests, refactoring and continuous integration...
Despite several attempts in repeating that, it seems like many people missed the part that I explicitly stated: I wasn't trying to say that tests are not valuable. I was trying to talk about the blind faith that people put in tests.
Now, to Denis's comment. Yes, I would be able to ship periodically without tests.
I am not talking in the air, I have the practical experience and two years of a running project to back me up on that. We had a CI process in place, which deploy the application to a staging server, and that was it. Refactoring... is not a subject that I can talk about in the context of this application without first explaining the architecture.
I came to that project shortly after finishing up a project that was... problematic. And I was determined to avoid the same mistakes. One of the first thing that we did was to define the core parts of the system, and build just enough of that to serve us. So far, this is normal, except that we added a tiny twist.
We applied the Open Close Principle as a holistic view for the entire project. If we needed to change a line of existing code, that was a bug, and we had to refactor that area of the system to make sure that the next time we need to change this, we wouldn't have to change existing code. Adding a new feature consisted entirely of adding new code.
We didn't touch existing code. Well, not very often, to be honest. This is the same project where I spent three months straight without even once going to the infrastructure directory, indeed, after three months we run into a problem, and it took me 10 minutes to remember that we are using a container in the app, and that the new class didn't match our convention, so Binsor did not register it.
A lot of my ideas about zero friction development came directly from this project.
Because we always wrote new code, and each feature was isolated from all other features, we were able to keep a rapid pace of development for the lifetime of the project. I mentioned that we didn't have automated tests, we didn't feel the lack. Off the top of my head, I can't recall any regression bugs that we had, except with infrastructure going bad (IT admins removing our shared storage, BizTalk changes we weren't told about, stuff like that).
I am pretty sure that there were some, but I can't think of any, so that put them at a very low number. And some stats about the project. It is running for 2 years (I left after the first year, and the team continued to provide new features and releases after I left), currently at over 200,000 lines of code, is considered a major success from the business point of view and its scope has tripled since the original inception.
And just to reiterate, I like tests. I think that they are important and that they have proven themselves in the field. BUT, They aren't a silver bullet, having them wouldn't make the project succeed. And not having tests wouldn't make the project fail.
Comments
Hi Ayendy,
I’m fully agree with your conclusion that “unit tests are not silver bullet”, in IT in generally we don’t have “silver bullets” (or in mostly cases we don’t have) we just do some practices which can minimize our “pain”, it doesn’t necessary mean that will help us to deliver, increase quality etc.. Because there are a lot of other factors which should be considered, these practices just can increase our probability to deliver (and in mostly cases by practice, it does).
Oren, I'd like to give you an [American?] high five for that post. Someone rubbed me the wrong way about the unit testing mantra from the beginning and you're providing me support -- not just inane ramblings (not all discussions of unit testing are inane), about the benefits without no solid evidence.
Now let me ask you something: to the extent that you can comment on this, what characteristics did your approach require that your team of devs had? I could pull out the word "Mort" and ask you to relate, but just use your own words -- they're usually plenty succinct, and I can often understand the first time around. :-)
Ayende, about tests, your last paragraph says all! I can't agree more!
Luke,
I am not sure that I understand what you mean by the question.
I had a good team in that project, talented, passionate and smarter than me in actually applying the knowledge in ways that I wouldn't have thought of.
They didn't have as much breadth of knowledge, perhaps, and they didn't have experience with unit testing, though.
Hahahaha, I was too succinct for Oren. This must be a record, no?
You must have seen this critique coming:
"The only reason your technique worked was because you were working with smart people. That doesn't work for most folks."
My running hypothesis on this is that most people are being held back by technology and management. I think most people could write better code (and do better architecture) if it required less of their energy to do so (some of us just have more energy to put into computers than other). I think it's possible to lower the energy requirements and it seems that you do, too. However, I would like to hear you talk about this a bit.
Oh my, not at all.
I used a similar approach in another project, where the team that I had was of integrators, not developers.
It was very successful (given my starting point), and it served to further validate this approach.
Could you write a bit more to combat that very common critique? I mean, yes, you were able to get it to work and you're very smart and also _experienced_. A bit more discussion would, I think, benefit many of your subscribers. "It worked for me" is not so useful. I know you've written a bit about this stuff before, but at least I would appreciate something more concentrated.
Luke,
See my posts about JFHCI for more details.
Otherwise, I would like to get a list of concrete questions that I'll be able to work from.
Can you compile one?
Can you give me a starting point? From quickly running this search, one didn't stand out:
www.google.com/search?q=JFHCI+site:ayende.com
I think one thing that may be missing from this discussion is the power of great leadership. I have seen projects lead by various levels of leaders and at the end of the day I believe 100% that a successful project needs a great leader. And by successful I don't mean it shipped because I have been on projects that "shipped" but I didn't consider anywhere near successful in terms of creating a maintainable, trust able application that fulfilled the customers real needs.
In this example it seems obvious that this open closed architecture was Oren's idea and without him the project would have gone in a more normal direction. I suspect that this more normal direction which would have resulted in a project that was much less successful.
You should deprecate the other post - this one says it much better. It is sad that composite architectures are so little-known, and so terribly tooled.
Besides the obvious dependency inversion stuff, is there some toolset that anyone recommends for achieving composite architectures? Challenges I have encountered are security authorization (& authentication sometimes), UI merging (how do pieces of the UI from different components integrate) and module communication (how do modules communicate in a low-friction manner).
Steve,
If you take the Prism guidance, and apply it to a non UI system, you get a lot of that behavior.
I just finished recording an hour talk with Luke about this topic, and I would publish it in a few days.
This is somewhat similar to something I've been banging on about for a while. why is it that some software needs an endless amount of testing, and the only way to cope with this expanding burden of testing is to automate, automate, automate. But some systems don't need it. I think the essence is
"..if the problem is neat the code can be neat as there are no special cases. And neat code is good because it is easy to test and easy to review, and that means that the implementation quality can be very high;"
it also means that number once the code works at all then system integration tests are sufficient.
The rest is here:
nomorehacks.wordpress.com/.../building-stable-a...
Comment preview