21

Most, if not all IT people I know believe that it is beneficial to model software with UML or other types of diagrams before coding. (My question is not about UML specifically, it could be any graphical or textual description of the software design.)

I am not so sure about it. The main reason is: Code doesn't lie. It is checked by the compiler or interpreter. It hopefully has automated tests and needs to pass static code analysis. If a module does not interface correctly with another module, it is usually obvious in code because you get an error message.

All of this cannot be done with diagrams and other documents. Yes, there are tools that check UML, but everything I've seen so far is very limited. Therefore these documents tend to be incomplete, inconsistent or simpy false.

Even if the diagrams themselves are consistent, you cannot be sure that the code actually implements them. Yes, there are code generators, but they never generate all of the code.

I sometimes feel like the obsession with modeling results from the assumption that code inevitably has to be some incomprehensible mess that architects, designers or other well-paid people who get the big picture should not have to deal with. Otherwise it would get way too expensive. Therefore all design decisions should be moved away from code. Code itself should be left to specialists (code monkeys) who are able to write (and maybe read) it but don't have to deal with anything else. This probably made sense when assembler was the only option, but modern languages allow you to code at a very high level of abstraction. Therefore I don't really see the need for modeling any more.

What arguments for modeling software systems am I missing?

By the way, I do believe that diagrams are a great way to document and communicate certain aspects of software design but that does not mean we should base software design on them.

Clarification:

The question has been put on hold as being unclear. Therefore let me add some explanation:

I am asking if it makes sense to use (non-code) documents that model the software as the primary source of truth about software design. I do not have the case in mind where a significant portion of the code is automatically generated from these documents. If this was the case, I would consider the documents themselves as source code and not as a model.

I listed some disadvantages of this procedure that make me wonder why so many people (in my experience) consider it as the preferable way of doing software design.

10
  • 1
    Possible duplicate of What is a simple process for designing an OOP system before coding it?
    – Doc Brown
    Commented Aug 15, 2017 at 21:20
  • 5
    I think it's a completely valid question. If our model has any value, it has to match the code. So why not design the model in the same language that we later use to implement it? Then they're always in sync. And if you prefer fancy graphics, they can be generated from code. Commented Aug 15, 2017 at 21:42
  • 3
    You should get to know more "IT" people then. Or perhaps I should say, you should become familiar with more communities within that umbrella. Commented Aug 16, 2017 at 2:04
  • @DocBrown: While the answers to that question and especially the articles linked in your comment do provide relevant information, the original question is very different. Commented Aug 16, 2017 at 8:01
  • @FrankPuffer: I am aware of that, voted to reopen. Nevertheless I think the core of your question - "what is software design" and "the role of modeling in software design", is a very broad question, maybe too broad to be answered here in a sensible way.
    – Doc Brown
    Commented Aug 16, 2017 at 8:48

5 Answers 5

25

The benefit of modeling software systems vs. all in code is: I can fit the model on a whiteboard.

I'm a big believer in the magic of communicating on one sheet of paper. If I tried to put code on the whiteboard, when teaching our system to new coders, there simply isn't any code at the needed level of abstraction that fits on a whiteboard.

I know the obsession with modeling that you're referring to. People doing things because that's how they've been done before, without thinking about why they're doing it. I've come to call it formalism. I prefer to work informally because it's harder to hide silliness behind tradition.

That doesn't mean I won't whip out a UML sketch now and then. But I'll never be the guy demanding you turn in a UML document before you can code. I might require that you take 5 minutes and find SOME way to explain what you're doing because I can't stand the existence of code that only one person understands.

Fowler identified different ways people use UML that he called UML modes. The dangerous thing with all of them is that they can be used to hide from doing useful work. If you're doing it to code using the mouse, well I've seen many try. Haven't seen anyone make that really work. If you're doing it to communicate you'd better make sure others understand you. If you're doing it to design you damn well better be finding and fixing problems as you work. If everything is going smoothly and most of your time is spent making the arrows look nice then knock it off and get back to work.

Most importantly, don't produce diagrams that you expect to be valid more than a day. If you somehow can, you've failed. Because software is meant to be soft. Do not spend weeks getting the diagrams just right. Just tell me what's going on. If you have to, use a napkin.

That said, I prefer coders who know their UML and their design patterns. They're easier to communicate with. So long as they know that producing diagrams is not a full time job.

7
  • 2
    "there simply isn't any code at that level of abstraction that fits on a whiteboard" That brings up an interesting question. Why not? What would have to be true for the entry point of a system to explain at a very high level what it does?
    – RubberDuck
    Commented Aug 15, 2017 at 22:07
  • 2
    Because code must be all things to all people (and at least one compiler). A model can have a focused audience. Commented Aug 15, 2017 at 23:03
  • I think using the word "formalism" for this is unfortunate. It either over-inflates what the "modellers" are doing, or it demeans actual formal modeling. (It also doesn't seem to really capture your intent from what I can tell here. Your concern doesn't seem to be with the modeling itself but with using it as a gate or for bureaucratic reasons even when it's not adding value.) Commented Aug 16, 2017 at 2:03
  • 3
    My problem isn't with modeling. It's with using formal ceremonies as a replacement for critical thinking. I'm trying to say a lot of the model bashing happens because much of modeling fell in with that crowd. Modeling can be very good. But it has a dark side. Commented Aug 16, 2017 at 2:23
  • 1
    "I can fit the model on a whiteboard" is a very concrete (excellent!) way of saying "I can make an abstraction of something that is more complicated to help understand or communicate aspect I feel is important." This is what good modeling does in general, whether it be software or anything else complex. Commented Aug 16, 2017 at 13:21
6

I am asking if it makes sense to use (non-code) documents that model the software as the primary source of truth about software design

No. This never makes sense. Your code is your primary design document, ie "the primary source of truth about software design". Only the code describes exactly what the application does as the compiler takes that design and creates the application from it.

By all means use diagrams as supplementary design documents, though if they aren't auto-generated from the code, beware them telling a different story to the real design. If UML floats your boat, use that. If not, use something else.

Some folk find it useful to sketch out their thinking in diagram form before starting to write code. But remember what Uncle Bob said on this matter:

"So, yes, diagrams can be inappropriate at times. When are they inappropriate? When you create them without code to validate them, and then intend to follow them. There is nothing wrong with drawing a diagram to explore an idea."

If you do use UML to explore a design, throw them away when you start coding. Write a test, then write some code to make it pass. Repeat. That way, you'll end up with a validated design. UML cannot ever offer you that same level of validation of your design.

2
  • A counter example (?):: model-view separation (or any GoF pattern) can be easily drawn as an intended truth of design (blueprint) proposed by an architect. Developers who stray from that intention do not render useless the (intended) model. Yes, the code is the "truth" but it's not necessarily the design. Validation doesn't have to be automatic with UML or some model. The fact that it is not doesn't make a model trash-worthy. Commented Aug 16, 2017 at 12:07
  • As for tests, I'm not sure it's useful to validate a design. Can you write tests that show that domain logic is not in the presentation layer (a very common problem with implementations that stray from an intended design)? Showing a diagram of the layers to a developer and explaining that an actionPerformed() method is in the presentation layer, and that it should simply pass control to the domain layer, is a key aspect of separation. (Trivial example, but it can be applied to all kinds of design strategies that are not easy to show just in code). Commented Aug 16, 2017 at 13:31
6

Most, if not all IT people I know believe that it is beneficial to model software with UML or other types of diagrams before coding.

I don't disagree that all of the people you know believe this, but I don't think it's necessarily common across the board. In 1970, Winston Royce knew that software development had some level of iteration between design and code activities. In 1992, Jack Reeves wrote about coding being the true design activity (also discussed on the C2 Wiki).

This doesn't mean that people have tried to make model-driven development tools. There are tools that attempt to generate code from UML models (and not just class diagrams, but linking various diagram types together and generating code from them). But those aren't, at least from what I've seen, widely used tools.

This also doesn't mean that you should go right from requirements into writing code. There are certain design decisions that are critical to get right early and some level of modeling can be useful to make sure that everyone understands the options, their impact, and can communicate. Some people (including myself) call this the "software architecture".

Code doesn't lie. It is checked by the compiler or interpreter. It hopefully has automated tests and needs to pass static code analysis. If a module does not interface correctly with another module, it is usually obvious in code because you get an error message.

This is really the heart of some of the aspects of Agile Modeling, especially Executable Specifications and Single Source of Information. I don't necessarily agree with TDD, but the idea of having your code and associated tests (from unit through acceptance tests, preferably captured as automated tests) be the single source of truth is a good idea.

Even if the diagrams themselves are consistent, you cannot be sure that the code actually implements them. Yes, there are code generators, but they never generate all of the code.

I think as a general rule, going from model->code is the wrong way. Instead, the code should generate models. That is, tools should be able to examine code and generate graphical and tabular representations that can be further enhanced as engineers write text around them. And this generation of models from code should be a seamless part of a build and release process.

There are tools that, to varying degrees, do support this for various languages. Given the nature of languages and paradigms, it's easier for some than others.

I listed some disadvantages of this procedure that make me wonder why so many people (in my experience) consider it as the preferable way of doing software design.

I don't think that these people necessarily understand software engineering and software design. I think that these people are looking at what other engineering disciplines do and mapping it to things that they think that software engineers should do. But they are ignoring one major difference. Other engineering disciplines create models and simulations first because it's extremely expensive and time-consuming to build the actual product. In software engineering, we can take pieces of our design and produce something that is testable in a real-world environment in very little time and with very little cost. The economics are very different.

What are the benefits of modeling software systems vs. doing it all in code?

When you have an extremely complex software system, having models means having something that is easier to understand. It's a different level of abstraction, something to help people understand various facets of your system. It's one of the reasons why there are so many different modeling languages and different types of models allowed by each modeling language or notation - to allow different stakeholders to understand, conceptually, the software system quickly and easily.

6

I am asking if it makes sense to use (non-code) documents that model the software as the primary source of truth about software design. I do not have the case in mind where a significant portion of the code is automatically generated from these documents. If this was the case, I would consider the documents themselves as source code and not as a model.

Plenty of non-code documents are useful as blueprints. That is, the "truth" of the design should follow this direction. It's a way to model elements that a design must fulfill. You could call them requirements documents, but that is maybe too strong in all the examples I could give. I've used PlantUML via PlantText.com to produce these.

  • Use-case diagrams can show the intended features and interactions with users or external systems. enter image description here

  • Activity diagrams can show business processes that a software needs to support. enter image description here

  • State diagrams could show intended dynamic on a web site: enter image description here

  • Gang of Four design patterns are presented as static and dynamic models. For example, Memento:
    enter image description here
    enter image description here

I listed some disadvantages of this procedure that make me wonder why so many people (in my experience) consider it as the preferable way of doing software design.

If you're interested in some real information about UML's use outside of your experience, there are some studies that were done (I tried to find links to non-paywall articles):

0

We developers love to use images to explain our world so here is one with the production of a car :

  • The car is the result of the production chain, same for the code (add the deployment process of course).
  • The design document of the car is the same as the design document of the software.

In our worlds, it often happens than those who conceive and make the design document are the same than the one that produce the code. That is not true in the others fields. However that doesn't mean you really are able to get the same level of quality by doing them all together.

By making those document first without coding (excluding anything like a proof of concept for fasability,...) :

  • You are sure to think before doing, coding once you know what you have to do is EASY.
  • You are able to put more experienced people focus on the most difficult part of your software : design, algorithm/math is any except for very specific purpose (embedded, real time, assembly).
  • You can delegate to less experienced people a good part of the coding process while the more experienced people only focus on he most critical part that need the level of their skill. Those less experienced people will learn a lot about that.
  • You can discuss with non IT people through image of your design document, while if you had only code you would have to extract an image of what you did, with all the risk to forget something (a forgotten listener somewhere ...). See CandiedOrange's answer for more aspect about communication.
  • When you have to make your software evolve, you can anticipate better what will be impact.
  • Design will make easy to cut piece of your software down and having piece of your software developped concurrently.
  • Write those damn reberbative unit test will be way easier when you don't have to get headaches about being to have cover all the cases while coding them, in a TDD approach coding the test before the code is easy.
  • ...

Note : those affirmation suppose that the code is really the reflect of the design and they're both keep up to date...

2
  • This answer describes a near best-case scenario. You mention one caveat at the end that's quite big by itself. There are many others. You can easily omit necessary aspects, under-estimate the complexity of some part, not factor in the constraints the libraries/frameworks you use impose, not factor in bugs in dependencies, not factor in performance or other non-functional requirements, overengineer, fail to anticipate changes, or simply not be that good at design. This best-case scenario is unlikely to be realized even roughly in a professional context. Commented Aug 17, 2017 at 2:37
  • If you start by only considering every caveat of everything, you won't go anywhere. Whatever method you use. And a long list of what you said is perfectly valid when doing only code.
    – Walfrat
    Commented Aug 17, 2017 at 6:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.