I'd rather outline the major components of a system by drawing (on real paper) simple boxes and lines, or write the code that implements the system.
Not sure what code-as-picture achieves - it's generally has worse tooling (less editable, less versionable, etc.) and tends to be used by 'architects' who don't write code, only for that UML to be essentially ignored by the coders on the ground.
The problem is that complex systems need complex design. As your design get more sophisticated, you need more sophisticated ways to communicate the design. Concepts like dependency, multiplicity, inheritance, inclusion, asynchronous message, exception, timed event are all things you can represent with boxes and lines, but unless you adorn the diagram with a huge amount of text you're not going to capture the distinctions between those different types of relationship.
It's not unlike any other language: I can use the word thought to describe something in my head that isn't physically manifested, but words like lie, memory, hypothesis, idea, belief, image, nostalgia, forecast, imagination are all used to distinguish between types of thoughts. If I used only simple words like "thought" then I wouldn't be able to express anything more sophisticated while still being concise.
In short, if you want to graphically describe something complex, you can either use a sophisticated visual language to do it concisely and unambiguously, or you can use a simple visual language and write tonnes of documentation to support it, with all the problems of attention, ambiguity, and rot that go along with it.
The problem is that complex systems need complex design. As your design get more sophisticated, you need more sophisticated ways to communicate the design
No. Complex systems need more thinking and refactoring until they are less complex.
It's incredibly naive (or at best disingenuous) to assume that complex systems can be reduced by thinking and refactoring. Perhaps some can, but when you consider many of the software artefacts we use daily (seeing as that's the context of this subthread), such as operating systems, virtualization platforms, or even good ol' clunky enterprise applications, you can't just wish the complexity away with a bit of hard work.
I'd be pretty surprised if any of the code that I am using to read this was designed with detailed UML diagrams.
It wouldn't have been possible at all if the pieces that make it up weren't loosely coupled.
>It's incredibly naive (or at best disingenuous) to assume that complex systems can be reduced by thinking and refactoring.
It's naive to assume that you can't. Loose coupling pretty much only comes as a result of extensive refactoring.
Google for "linux kernel diagram". It's quite well designed, displays loose coupling, high cohesion, and all the other things we like about good complex systems. If I want to dig in and start working on a module, I'd still have to understand the relationship between all the bits I work directly with (and probably some that are further away).
Don't confuse loose coupling with low complexity.
We already have a perfectly good way of representing the details of a system - it's called source code.
Interestingly enough, that's a bit of a false dichotomy.
Imagine it's your first day on the team, and there's thirty classes (or thirty functions) in this software package, and you want to understand their inheritance/composition, what's a good way to take a step back and just see how they relate to each other? You can browse some interface files or some source files, accumulating a model in your head. But the visual throughput into your brain is just so much better when you can see it in a diagram.
Regardless of whether a human draws the UML representation of the design in advance of the implementation or a machine deduces this from the existing source code, you can still benefit from a class diagram that will cut out the noise of the implementation itself. As long as we're drawing a diagram, why not have a common way to represent the concepts we use in software?
> perfectly good way of representing the details of a system - it's called source code.
> simply use a tool to generate a class diagram from the code
Once you resolve to generate that class diagram you have a choice in how to represent it. UML is just one way, proposed as a standard way, to represent that visually.
The problem of UML is that it tries to be the language of all these levels of design (and even different stages of design!), to the point that the highest-level design document is trying to be something so completely specified that there's no abstraction.
One of the most constructive things you can do when designing software as a part of a team is to review these diagrams with the team. Inevitably, if you create boxes and lines, you'll need some sort of legend that identifies the relationships established by the visual style of boxes and lines. UML is intended to be a common legend, like the schematic representation of circuits (resistors, capacitors, diodes, grounds, etc).
> Not sure what code-as-picture achieves - it's generally has worse tooling (less editable, less versionable, etc.) and tends to be used by 'architects' who don't write code, only for that UML to be essentially ignored by the coders on the ground.
An error that happens more often than we'd like to admit is when we totally mis-assess the requirements or omit big portions of an element's design. Sketching a quick diagram that shows "the UserAccount has a user_name, user_id, and a password_hash element" allows the team to sanity check the design approach -- "Oh, but a UserAccount also needs an email_addr element." "Are you kidding? How would we email them, there's no interface for that on this system." It's sad, but sometimes entire (enormous) features like this don't get caught until much later in the design cycle.
There are definitely better techniques than waiting until someone quibbles a field in a lines-and-boxes design session to pull that kind of insight out though. Just sitting around and telling stories about what the user will be able to do, and how they will be able to do it can work wonders.
But of course, that is exactly the opposite of what UML set out to achieve: a system so formal and complete that it could be used to generate code automatically.
Believe it or not, the customers understood it perfectly, after some minutes drawing and deleting lines. There was never a single complaint about that module and only minor bugs, not affecting to the functionality.
I hated use cases diagrams, only useful for CYA purposes. The classes diagrams that I've seen in the wild were E/R models translated to UML, but they were the most part of documentation for some projects, so it was better than nothing.
The traceability systems from requirements to complete UML diagrams to code were a bunch of good intentions that fortunately never materialized.
I found it to be a pain as a student (it clearly was a fad at that point), but every time I go back to shipped code in mainstream paradigms, I understand why people went this way. It's as boring as intractable. We don't want to code at that level, we want abstractions, but these paradigms didn't help so we needed diagrams. And it's an offspring of OOP mostly which helped reducing cpp-like complexity but not for free.
IMO UML boils down to a visual type checker. We can layout things more efficiently than with linear text, and can appreciate the relationships between parts. But in a way, that's what a type checker does. I remember never needing a diagram (for medium single person programs that is) in Eclipse since it could look at the whole system for me and show contradictions or suggest options.
I'm now very regularly tempted to do things with a bit of empty interface logic checking, FP-ish minded. You can still write this as text, and as long as it the types flow logically it's OK.
ps: this was also influenced a bit by posts like these https://www.google.com/search?q=f+sharp+uml
I used to work on a CASE tool early in my career. I was always struck by the fact that we never ate our own dog food; that is, we never employed the tool we were working on to guide its own construction. This was the first time my eyes were opened to the fact that perhaps there was a lot of junk being built :)
CASE itself I believe was an attempt to replicate for assembling bits some of the benefits CAD/CAM was bringing to assembling atoms.
Although the latter is partly because the idea of doing 'SE' without the 'CA' is now inconcievable, even to senior management.
Same about dogfooding. When I realized RSA wasn't (at least when I was working on it) developed with RSA or any UML I felt weird... Doubly weird since other tools like IBM Jazz (team collaboration) used themselves to ensure a certain dose of value.
Nobody forces you to use software to draw UML diagrams and nobody forces you to include every aspect of your objects in the UML diagram. The basic idea of UML is pretty sane, many people just overdo it.
Informal UML diagrams - dynamic box-and-line relationship diagrams scrawled on a whiteboard where one arrow has been drawn in extra thick to emphasize a point; sequence diagrams where one colleague has drawn the sequence arrows as they work today and another has scribbled over the top the arrows as they should work in a different dry-wipe color; those are an appropriate use for "sort-of-UML" - as tools in rapid communication of ideas. My phone's full of photos of that kind of UML. But at that level of formality, nobody should mind if you get the open or filled diamond arrowheads wrong, or you use arrows for one to many relationships instead of inheritance, so long as everybody working on the diagram understands what is meant in that moment.
UML is a formal standard for back-of-the-envelope doodles, and that is exactly as ridiculous as it sounds.
however, I found that a good sequence diagram here and there and a deployment diagram could really ease up communication when comparing the critical points of two or more different solutions - if done at the right level of detail.
I get your opinion from a programmer point of view. However from the big picture point of view, either from the architect or from the client (if she (even partially) gets UML), it could be really useful.
E.g. let's consider working for a large financial institute, designing and/or implementing very difficult workflows / algorithms what would you use instead? In my experience most of the clients don't take the time to read half (if at all) of the agreed spec, not to mention understanding. In that case an activity/state diagram really helped a lot.
And on not versionable: you are right only to an extent (e.g. exported Visio diagrams to JPG...). However there are tools/methods, which can be versioned (e.g. generetaing UML via Graphviz/dot, and AFAIK Enterprise Architect supports versioning too).
I understand you, but the problem of simple drawings is that is not a common language broadly understood.
Another good use case for UML is the visualization of complex flows in frameworks.