views:

211

answers:

4

I have been looking to expand my methodologies to better involve Unit testing, and i stumbled upon Behavioral Driven Design (Namely Cucumber, and a few others). I am quite intrigued by the concept as i have never been able to properly design top down, only because keeping track of the design gets lost without a decent way to record it.

So on that note, in a mostly language agnostic way, are there any useful tools out there i am (probably) unaware of? Eg, i have often been tempted to try building flow charts for my programs, but i am not sure how much that will help, and it seems a bit confusing to me how i could make a complex enough flow chart to handle the logic of a full program, and all its features.. ie, it just seems like flow charts would be limiting in the design scheme.. or possibly grow to an unmaintainable scale. BDD methods are nice, but with a system that is so tied to structure, tying into the language and unit testing seems like a must (for it to be worth it) and it seems to be hard to find something to work well with both Python and Java (my two main languages).

So anyway.. on that note, any comments are much appreciated. I have searched around on here and it seems like top down design is a well discussed topic, but i haven't seen too much reference to tools themselves, eg, flow chart programs, etc. I am on Linux, if it matters (in the case of programs).

A: 

I hate to say this but you're probably need to do the exact opposite -instead of designing the whole system up front use TDD/BDD and your tests will drive the design.

The problem with design tools and diagrams is that the become obsolete the minute you start writing and refactoring your code.

By writing tests you make sure toy only implement what is needed and that you code works - so you do not need a design tool just a few guidelines and user stories.

Dror Helper
...I do not fully agree, see my answer:)
Gabriel Ščerbák
+1  A: 

It is really a good question. BDD and TDD and agile in general do not say you cannot do up front design, they just say don't design more than you need - defer any decision as late as you can. I am sure there is a set of tools which you know, which is exactly used for that, it is called UML:). You were absolutely right when you hinted at the effort aspect. As long as UML diagrams are just pictures, they became throw-away waste and maintenance burden during development, when things might change quickly and rapidly. However, you can use some CASE tool, which will allow you (after months of swearing:D...) to create diagrams, which can be used to generate code and when you would need to change something at the model level, just change diagram and regenerate (this actually needs some architecture and work beforehand, look at some model driven approaches). What I think in this regard is the best, would be something in the middle. Something, which will enable you to easily model (draw and maintaine diagrams, flowcharts, state machines...) and allow you to generate code. What I see as the best approach are (external) Domain Specific Languages. E.g. you can use tools like Xtext to create a language for state machines and generate code for them e.g. according to the GoF State pattern (or you can use the SMC tool, which does that only for state machines) to imlement business rules. Combine that with BDD and you can easily discover some problems and you can easily change the rules without damaging the existing code (thanks to the design pattern). What I am aiming for in my masters thesis is to create set of many DSLs, which will enable you to describe interaction with the application the BDD way, but will allow you not to just generate tests like Cucumber, but also the (partial) application layout (if you want to see a button at some page, obviously, on that page you want to have that button...). You also interact with some domain objects, which can be modeled according to used architecture, for example in the Domain Driven Design style. I think this is quite realistic and it really pays of to model then. For top-down design, you need some sort of abstraction to move from top to down, so some design up front is necessary.

Gabriel Ščerbák
+1  A: 

Well, I give you my 2 cents on that matter. I agree with Gabriel when he says that UML is the tool you are looking for. UML as its name states is a langage to model your application. I also agree with Dror when he says that a lot of design tools fails when you begin to refactor your code. It is a pain to try to get your diagram follow your code. You have two main possibilities :

  • Use UML and UML tools to design high level application architecture or main modules. It helps to have the big picture in mind and highlight the main problems you can have. When you start to code & refactor, do not try to make your diagram up to date. Forget them. You can come back to them on the next big iteration of your design.
  • Use a tool able to handle synchronisation between code and design. In my experience the only tool able to do that was Borland Together. (I have not used it for a long time ...)

In any case, two key points, in my humble opinion :

  • before design, specify your needs (use cases, user stories, requirements, whatever method you prefer).
  • The tools you use must be understood by anyone who work on the project. If the team working on a project has not a clear understanding of the tools, it will be counter productive to use them. I've tried to use tools like together in the past, and as it can work with people used to UML design, it fails with people not used to this sort of tools.

    my2c

neuro
+1  A: 

Two-part answer

The methodology of Divide and conquer is pretty straight-forward:

  • Think of the algorithm in the most abstract sense. What needs to be done?

  • Break down the problem into sub-problems. And do this recursively until these become simple enough to be solved directly.

  • To keep things tidy. Let one function/method only have one purpose. A long and complex function is a pretty good indication that you need to break it down further.

Refactoring then becomes the process of finding and removing duplicated code. If you have not had any experience with functional programming yet, you should at least try it out for the learning experience. You will come to find that this way of thinking helps doing top-down design very well.


Unit testing is all about knowing your dependencies. You will learn never to have a global state (not even singletons), and to use dependency injection.

This makes your code easy to test because you can easily test a singe class in separation! Without this technique your unit tests will eventually become too complex because they not only test the class itself, but also all its dependencies...

If you have an hour, I highly recommend this Google Design Tech Talk: OO Design for Testability.

bitc
Thanks for the video link, i'll be checking that out tonight!
Lee Olayvar