I like the middle-out development that is achieved with DDD. Development is driven by domain, the most 开发者_StackOverflow中文版solid part of application. We don't depend on infrastructure, persistence and presentation. That sounds good. But it has no business value.
Here comes business-focused BDD with outside-in development. We have no upfront domain design (choosing entities, value objects, aggregates). We take user story, write some scenarios and implement them one-by-one. We start development from most changeable part of application - from presentation. I hate writing fragile acceptance tests. Do you?
So, if someone here have successful stories about applying DDD in BDD style, please share some with me :)
- Do you write those fragile tests for presentation?
- Do you have some design upfront before creating part of domain for user story that is implemented? Or you refactor towards DDD patterns after implementing story?
Any help will be appreciated. Thanks!
I offer Dan North and myself (please excuse the rabbit in the headlights look, it was my first video) being interviewed by one of Eric Evans' colleagues on BDD and DDD.
Also you can have a sneak preview of a segment of the draft first chapter from a BDD book I'm writing (hopefully with Dan too):
As another effect, discussing the scenarios without any technical words, in business language, allowed the developers to pick up that language. They then carried that language into their codebase, implementing classes named after elements of the business domain, methods named after capabilities of those elements, and properties and variables named after their real-life properties and sub-elements.
This use of business terminology in code is referred to as the ubiquitous language in Eric Evans' book, "Domain Driven Design". Eric suggests that when developers start to code in a language which matches business stakeholders' terminology, conversations become fluid, without the need for developers (or analysts as a proxy) to translate back and forth from technical details to domain concepts. The code becomes more readable and easier for newcomers to understand. The value of each object in the system becomes more obvious, as well as the path by which it provides its value back to the user so that the user could provide value to the business.
JBehave introduced something new. Not only were the developers using business domain language; they were now using a language that the business understood to describe software terminology. Instead of words like test, acceptance test, act, arrange, assert, red bar and green bar, developers were talking about examples, scenarios, contexts, events, outcomes and behaviour.
JBehave, and BDD, had introduced a ubiquitous language for software development itself.
Hope this shows that BDD and DDD work very well together indeed. All feedback welcome, except on my dress sense.
Edit: You're right, the domain is pretty solid. That's why we focus on the more risky stuff like presentation and infrastructure, and talk about our understanding of the domain using scenarios. We can't get feedback on our understanding of the domain until we have something to get feedback with - but it doesn't stop us seeking the understanding anyway.
Let me add the precursor to my answer that I am in no way a BDD, TDD or test first expert. Digressing...
I have found all test first development methodologies to require crystal ball level clairvoyant premonition when started from scratch for a high level of success. Since that is completely impractical, I find this level of testing only makes sense well after the prototyping period that core DDD has been fleshed out. Along with other core architecture decisions are put into place that there is a clear thought process on how to achieve success.
Being an enterprise architect my #1 thoughts in project development are always repeatable success. This is always far more achievable when the core architecture will be consistent between projects, and even more importantly so in the same project.
Now to answer your question directly, in my book DDD always would come first. Without DDD it is my opinion you are basically stabbing in the dark when it comes to key architecture design decisions which could become immensely painful later. DDD is also much more of a higher level concept in my view that it is expressed in high level block diagrams. With many BDD stories that will comprise the DDD level interaction between systems.
In regards to the question about whether I would write stories for UI interaction, there is definitely value in them. Nevertheless they could easily become skipped in lieu of time needed for other endeavors as project constraints tend to always arise sooner than expected. Coded UI tests you write do not have to be fragile. However, if they are fragile they're nearly purposeless to begin with. If you follow a clear cut convention of HTML element naming, along with writing semantic HTML you can create very reliable UI unit tests. This much more easily expressed in MVC as opposed to webforms (in ASP.NET, java probably has some kind of similar parallel).
RE: you suggest to create scratch of domain prior to implementing stories?
I would even generally go a bit further with defining Model class concepts, and service interfaces. At that point when implementation of interfaces is starting is when I would start working on the stories. This would also then lead to changes in the models or interfaces as they arise. To leave the entire service interfaces, and models to be designed as they evolve from stories I feel would produce too much tunnel vision. That you'll start making models and/or interfaces that solve a specific story but make little to no sense for the bigger picture.
So to really summarize on your question of middle-out, vs outside-in. I feel they are very capable of building on each other, more so if you start with DDD middle-out for overall concepts, and then work outside-in for the details. I feel doing that process in reverse would lead to much more refactoring than necessary, and much tougher refactoring as you would be trying to pull your core domain out of a collection of related stories that were most likely developed in a silo.
I was lucky enough to get to do one of Gojko Adzic's 'Specification by Example' workshops in June this year.
Gojko made reference to Eric Evans and DDD throughout the class.
The lightbulb moment for me was when the exercise we were doing lead us to refactor the domain model 'for deeper knowledge' That is, as we gained a deeper insight into the domain, we refactored the model and with it the BDD tests to reflect that insight.
The example in the class was a Blackjack game where we were initially modelling a hand of cards as an integer value based on the sum total of the cards. As we came to a deeper understanding of how the Blackjack game worked we introduced the concept of a hand being a 'Blackjack' hand, so moved away from using an integer value to represent the hand to it being either an integer value or a 'Blackjack' hand.
In my practice I seek to evolve the Domain Model and its ubiquitous language. I then use that ubiquitous language in my BDD tests.
I can't see why it shouldn't work? BDD is behavior driven development, that is, aboout your development process, which could (should) impact your design. DDD is domain driven design and is more about the overall design of your system. To make a long story short, in BDD (or any other xDD) you define how something should work and then it is up to your domain to realize those requirements. If you implement those requirements using DDD or something else shouldn't matter... you still need a green mark next to that test.
UPDATE: I don't think DDD is about direction, for me DDD is about keeping your code clean. I would say that using BDD is a way to help keeping your code clean, if you start with just implementing your domain you might end up with a domain that is too complex. The way I would like to do it is to use BDD to define my features (like log in functionality) and different scenarios (like successful and unsuccessful log in). After that I wouldn't write some unit tests so I have something that test the code and not the behavior. When I have implemented so the unit tests pass hopefully the BDD test pass as well. After that it is time for refactoring and during the refactoring all your tests should stay green. You can see it as two cycles, an outer cycle that tests the behavior (BDD) and one inner circle that tests the implementation (TDD). This should not stop you from using DDD principles, instead I would say it would make it easier to keep your domain clean and solving your actual problem at hand.
Update 2 (links):
- Presentation from mvcConf (online conference) about BDD combined with TDD: http://channel9.msdn.com/Series/mvcConf/mvcConf-2-Brandom-Satrom-BDD-in-ASPNET-MVC-using-SpecFlow-WatiN-and-WatiN-Test-Helpers
- A presentation from QCon about BDD and DDD, http://www.infoq.com/presentations/bdd-and-ddd. I haven't seen it myself but it look promising.
Yes, I believe BDD and DDD can be used togethor. Here is a C# test framework that may help towards this
http://kernowcode.github.io/UBADDAS/
In short: Yes, Specially in knowledge crunching we can use BDD and DDD tools to have a better model, As you might know, every tool might have some blind spots and errors; I usually use Event storming and Example Mapping at the same time. This approach will help us to have better UL. for more checks this.
精彩评论