My university SE class was during those heady days of MDA, and my opinion, nicely summed up in this article, hasn't changed one bit:
Yes, I could create a class diagram as a PIM; press a button and create a PSM; and press another button and generate Java code. But the Java code had all sorts of holes in it that I had to fill in — and if I changed the model in any way, half of the code I'd written would no longer compile, let alone run correctly. In other words, OptimalJ automated the most trivial things, leaving all the hard work to the end user.
Unfortunately while MDA died, this same scheme is dominant today for OpenAPI definitions with exactly the same problems.
Oh wow, thank you for the reminder. I started work consulting on a project recently where the team is using protobufs and grpc. While they aren't directly changing the generated files, they aren't keeping them appropriately gapped. I knew this problem had been around since forever, but I couldn't remember where I'd seen it covered. This is exactly the pattern I had in mind but couldn't remember. I hope that I can help the team overcome some difficulties by discussing this with them.
IMO this works for RPCs, ORMs, and certain event streaming architectures but not REST APIs beyond some trivial cases. As soon as you might want separate middleware processors but the same terminal handler it starts breaking down.
This idea we could work as little ants on a factory chain still persists to this day, but UML was the bravest most expensive attempt at "no-code" industrialization they've attempted.
Sadly, again and again, it is all destroyed by the client-facing people: "guys, the clients cant see the button can you make it yellow" and its infinite never ending variations, which make our job more akin to a jeweller because no amount of pre-code rationalization will prevent post-production resculpting.
It wasn't even "no-code" since you actually had to write the implementation. Yahoo Pipes was more no code than UML (I dearly miss that service).
It was a descriptive language, somehow useful to do nice charts, but the tools themselves were so bad the only reason devs used them is because of suspicious relationships between management and UML tool vendors...
> which make our job more akin to a jeweller because no amount of pre-code rationalization will prevent post-production resculpting.
Can I borrow that quote for my professional communications? This is so elegantly formulated.
UML had activity diagrams as its own pipe-like notation for low-level code. Not sure whether it was widely used, though. Also in general, conveying high-level data models might be more of a priority than implementations.
I've only ever seen activity diagrams used by business analysts to capture system dynamic behaviour at a very high level.
Mind you - as most people using activity diagrams have never heard of Petri Nets they were a bit vague about what forks and joins actually mean and were using them as convenient ways to join multiple arrows together....
When I was learning how to program, I programmed a graphics engine. It was about 10K lines of code, my first 10K in a single project.
At one point I was making an object loader and didn't understand what hashmaps and hashtables were. I was making mistakes, debugging constantly and the complexity grew over my head.
I sketched out a quick 'n dirty class diagram and how everything related. Whenever I got stuck or confused, I'd look at the class diagram. I'd see where I was and noted to myself what I already implemented and what still needed to be implemented. I also asked myself if I was stuck with a high level (UML) issue or more a low level issue (not understanding a certain datastructure).
That class diagram was my rock and emotional support in coding up that object loader. So UML does have its place: if it gets too complex, but you know the design, draw out a UML-like diagram (or other diagramming methods) and it'll allow you to not have the high level picture in mind: it's right behind you on the whiteboard.
Other than that, yea proper UML has never worked for me.
'Proper' UML not working for you is the entire problem. UML had some good ideas, but none of those good ideas are unique to UML. Drawing things and the relationships between things is awesome.
I've used UML to communicate certain things about code. Class or sequence diagrams are great tools to explain code structure or workflow. Of course it's not very frequent that I need to use them, but they're still useful.
Sure, but were those diagrams even conforming UML? And should they be?
I don't see a lot of value in UML's standardizing +,-,#,~ as access specifiers, vs just using the relevant language keywords.
Generally, unless people are using CASE tools, I tend to see them draw non-conforming diagrams that just roughly resemble what the UML spec says, and that is almost always good enough.
Diagrams are good, but having to worry about N different type of arrow heads, if a line should be solid or dashed, semi-obscure access symbols, etc is not good. and strictly speaking if you are not concerned about those things you are not actually using UML.
The exception is that nobody can ever convince me that a UML-style usecase diagram is better than alternatives like user stories.
It was definitely a waste of my student time. I had to take the class on my second year and spent a semester learning UML because the professor was all into it. We've just heard about OOP at that time, the biggest achievement was being good at Delphi, most of the class had trouble writing a hello world in any language.
The problem was also that the prof was always modelling some accounting/business "problems" which we also had no idea/experience about. So it was about learning couple of things all at once with very fragmented information. It was a disaster of class, and turned me off out of both UML and OOP. The latter I'm still sour about.
I remember being in scrums that used UML to generate code in the 00's. We just didn't wake up from the scrum delusions as quickly. I had read the agile manifesto, so when a manager told me as a young engineer that we were going to do agile I was momentarily overjoyed at the prospect of focusing on getting code working rather than our process or our UML tools... Then he showed me our new process, and I still had no choice in my tooling. So I said goodbye to that job. Sadly scrum has been harder to escape than UML.
It's too bound up with OOP, specifically C++ and Java. It is hard to represent entities that are not simple classes.
Things that are idiomatic (in 90s C++, cough) look very verbose. If you have a base class, a derived class, and an interface you have a lot of duplication. It makes things like polymorphism look needlessly complicated.
And finally, it is ugly and unintuitive. The inheritance arrow goes the wrong way. I know it is supposed to say "derived IS SUBCLASS OF base" and thus goes upwards, but in my mental model it is "you start with base, and then go to derived (get more specific)" so it should point down.
They, however, a) were pretty much the only actual UML's innovation: other things like sequence diagram have existed long before; b) had most emphasis put on them.
I'd say it's getting a wide audience agree on a common method of notation. I have a Java book from 1999-2000 which uses OMT (all right, OMT's object diagrams) as its main representation. Not too far off from UML class diagrams, as it is also considered a historical predecessor, but still enough to make me consult the legend time to time.
Sequence diagrams are not particularly helpful with JavaScript and alike and agree with parent OP that its too strictly tied to C++/Java. They are just not intuitive with async/await and function composition. Yes, one can always do "mental translation" to translate those into the diagram and vice versa, but just not helpful. Now one would argue that you model "more abstract processes" with them, but there are better modelling languages for business and network processes.
If I were reviewing a system design, yes, with js, I'd still like a sequence diagram. I'd just indicate that ordering may not be exact between certain bands of requests. I model concurrent systems all the time in sequence (ish) diagrams.
I want to know that action X will trigger N calls and those calls call service foo and bar, and that foo then calls out to its data store and eventually returns something and service bar calls services raz and quux and those each fist call a caching service before going to their data stores. All requests eventually return (in the happy path). Now, as a reviewer, I can quickly see what talks to what and why that call happens and I can ask more intelligent questions like what happens if a cache hit happens when the data store has been updated.
Well, I take issue with most formalized diagrams that represent code elements, rather than "business" entities. It leads to a kind of thinking that is wrong IMO, where you mechanically represent every business object by a class, say Customer and Employee.
I tend to think of OOP as a way to rewrite 'if's now. When you have the same huge 'if' or 'switch' in a couple of places, you can usually rewrite it to use polymorphism, and it becomes clearer. But it is totally fine to use procedural or functional idioms most of the time.
I don't know the whole breadth of the actual standard UML, and I don't know anybody who does. When I say UML, I mean as practiced and not as written, and that means: Boxes for classes, methods below, various kinds of arrows that I have to look up. For sure there are good parts in the standard, but that is not really relevant here.
As the sibling comment says, sequence diagrams are usually more useful. Or state machine diagrams. Or a diagram showing data dependencies.
Then you are not complaining about UML, but about the old school bad OO designs that UML is meant to support (along with old school good OO designs).
Without UML, such designs would be worse because they would be less documented: if you have a relatively concise class diagram in front of you it's easier to ponder about what each of the arrows and boxes means.
I hadn't heard of CRC Cards before, but after a google search, I'm realizing that I've definitely written something similar while whiteboarding an idea. Thanks for the tip.
IMO the arrows point to the right direction, in a sense that in my mental model arrows are typically owned by the pointer, not the pointee. The pointees are typically unaware of what points to them. A base class "doesn't know" what its derived classes are. Likewise a git commit doesn't know it's descendants either.
So in my mental model a derived class actively "points to" its base class. Likewise a child commit points to its parent/parents.
> A base class "doesn't know" what its derived classes are.
There's a high variability in that, especially when metaclasses get involved and inheritance is itself a protocol (and thus can be hooked into every which way).
I do agree with the rest of your comment though, to me it also makes a lot more sense for a derived class to point to its parent than the reverse.
"derived class actively "points to" its base class"
That make sense - pretty much every language I've used that supports inheritance class definitions refer to the class (or classes) they extend rather than the other way about.
A "this is not intuitive" argument can be made about every formalised system and is not interesting: It will always be true for someone, no matter what you do. Get used to it being otherwise, then it will not bother you anymore.
When it is a visual notation and the main purpose is that it is supposed to aid you in thinking, then I think being "intuitive" is one of the most important features.
I want to see a graphical representation of my "business" entities, not a more verbose 2D representation of my source code.
Not being intuitive isn’t the strongest argument against specialized notation. Programming languages aren’t intuitive either, yet we learned them. The rationale is that the arrow goes into the direction the #include or import would go. So it shows logical dependencies — both caller and implementer depend on the interface — and you can quickly see if there’s a dependency in the wrong direction somewhere.
I fully agree with UML being stuck in OO land, though, and I think that’s the actual problem. Lambdas don’t exist, or have to be verbosely represented as interfaces. Type-level programming doesn’t exist. Anything higher order is unrepresentable to begin with. You don’t have to use Haskell to run into those limits, modern C++ is enough, or Kotlin, or TypeScript. UML is basically useless if you’re doing anything more interesting than cranking out Java 1.4 era EJB boilerplate.
I think we need a slightly more specialised word than 'intuitive' and we don't have it. Something that has the flavour of ">80% of experts use one of [set] mental models, and this thing doesn't capture the essence of any of them".
That is a high bar, I'm not sure if UML meets it (wouldn't know, don't use UML, not intuitive enough for me). But I think something like SQL's syntax meets it - nobody would design a language with that syntax in this day and age, experts have settled on not using garbled pseudo-English. The experts who think "VERB GLYPH ADPOSITION symbol" (ie, SELECT * FROM table) is the simplest way to represent relational algebra just don't exist. Anyone competent would use some other grammar.
Doesn't UML have metaclasses, that could be used for type-level stuff? First-class functions should probably be represented via the Command pattern, which is ultimately a kind of defunctionalization (i.e. it's what high-level functions get compiled down to in actual code).
> i.e. it's what high-level functions get compiled down to in actual code
Yes, the Command pattern is what I vaguely alluded to in my message. The thing is, using a lower-level representation in something that’s meant to be an abstraction of the actual code makes zero sense to me.
I wonder, if you spend so much time writing fine-grained UML, aren't you already sort of programming? If so, wouldn't that time be better spent with an actual programming language with all the ergonomics and features you need?
It seems to me UML shouldn't be dealing with this fine-grained level of detail. It seems like a wasteful effort. Either design high-level, or get down to actual programming.
Even with Java 1.4 the obvious mapping of class diagrams to data structures made for terrible data structures. You end up with an interconnected maze of objects that is totally inefficient for the algorithms. The mess typically included redundant, bidirectional and cyclic links between objects and where an object's only purpose is to be a list of another type of object, someone ends up writing a more limited wrapper around std::list/Collection/whatever.
Managers were overly fond of the class diagrams because they could understand them. And dividing work between programmers by class rather than by logical feature somehow made sense to them. I recall one manager spending way too much time arranging to print a huge UML diagram across multiple sheets of A4, taping it to the wall and then annotating it constantly by hand.
But knowing it can still be useful for simple sketches. Similarly dynamic dispatch is a really useful tool for particular cases when programming – used alongside other non-OO techniques. Our industry follows fads and fashions to an amazing extent but when things fall out of favour the baby goes out with the bathwater.
>Programming languages aren’t intuitive either, yet we learned them.
While saying "it isn't intuitive" is a bit of a simplification, I think there is something to the argument.
I wonder if that is the case. Many programming languages do seem intuitive in light of other programming languages and other formal notation like math. The ones that don't are the ones I struggle with more. If I'm reading a new language and I see an '=' I can assume either a comparison or assignment. If I see a '<', I can normally interpret it as less than. The more a language violates this, the less intuitive I consider it and the harder it is to read through it without familiarity. This even applies among non-intuitive paradigms. OOP isn't what I would consider intuitive out the box (but then is anything), but once you know two languages implementation of OOP you can measure a third language's implementation as being intuitive to the exist pattern or not.
My experience with UML is that it was wholly new. It was as intuitive as the first programming language a person would learn if they didn't know math notation, which given the rate new students to programming know math notation, is a level of unintuitive that even most programming languages wouldn't have even as a first time language. Add in that many are introduced it alongside OOP in general (at least that was my experience in college) and it is even less intuitive than that.
So to that extent, I think I can criticize it as being non-intuitive even with the comparison to programming languages.
> OOP isn't what I would consider intuitive out the box
Paradigms aren't supposed to be intuitive.
Anyway, "intuitive once you grasp the fundamental ideas" is normally called "idiomatic" in informatics. I will second the other comment on this thread pushing that term.
Absolutely nothing about computers is intuitive. The entire area of knowledge is composed of fundamental paradigms and their extensions. Those can be "simple" or "idiomatic", but intuition doesn't go anywhere near them.
> I fully agree with UML being stuck in OO land, though, and I think that’s the actual problem. Lambdas don’t exist, or have to be verbosely represented as interfaces
From a code generation standpoint (e.g. cracking out EJB boilerplate), the concept of model-driven architecture is generally a flawed idea. Lack of lambda expressions isn't that significant in the face of ignoring the complexities of real systems.
I'm curious about the issues you've hit representing higher order types though - was this in a class-style diagram?
I cannot fathom developing software without UML. How can you even design a system without diagrams? It's simply impossible.
There isn't one software component that my multiple teams at Amazon have designed that didn't use some diagrams from UML. And I'm sure you can say the same for any team in any FAANG.
Sure we aren't gonna do a class diagram the vast majority of the time, but there will almost always be some component diagram, sequence diagram, activity diagram, etc.
Some of the parts of UML are dead because they're not a good time investment, especially when working in Agile (class diagrams), but I'd argue that 90% of the people that say they never used UML after school have used it without realizing.
Just look at this thread, 100% of the responses are saying that UML = Class diagram.
I started my career in the early 2000s in a big company on a big industrial project where several generations of contractors had already had their hands in. UML, rational rose, auto-generation of code that you had to manually correct, CORBA, manual tests, proprietary tooling...
It would take weeks to onboard newcomers, have them create unix account managed by some IT people in India so they could have access to the license of the proprietary point and click software to manage all this.
I think it was a time where decisions on tools were made by managers in the procurement teams. Selecting technology based on what they heard while golfing with their buddies or depending on kick backs they would get from providers.
Sorry, a little bit of a rant but to this day it still irks me to think how unproductive we were because of obvious bad choices. There is a silver lining though because during those years I learned more than any moments of my career. It taught me all the things that you definitely should not do if you want to be able to produce something useful at a reasonable cost. And one of them was to rely on UML for anything more than informally communicating simple designs with local team members.
While UML as a sketch had some use, it was a very predictable disaster when people tried to use it to automate away the 'coders'. It automated 5% trivial work that bothered nobody, while getting in the way when things got medium hard.
I wonder if the current crop of low code tools learned from the whole UML story. Any chance things will be better this time?
Diagrams are good for representing structure, and inherently less good at representing behaviour (as mentioned in the article). I recall that in the early 2000s some UML tool venders were pushing "round-trip automation" as a way of tackling this problem; basically you'd model your business domain with some class diagrams, generate some boilerplate code, write code for the actual behaviour and then the tool would magically suck all the behaviour logic back into the diagram. It sort of worked, for a couple of passes, until the tool failed to capture the precise semantics of some perfectly valid code (which was probably inevitable).
I'm hoping that the (somewhat-fine) distinction between no-code and low-code is made with the same problems in mind, that is, an acknowledgement that code is quite often the best way of expressing the behaviour of a system.
I still miss UML class diagrams being widely understood. At the peak of its popularity, you could go into a room with just about _any_ programmer, draw boxes and arrows on the whiteboard and everybody understood. People knew which arrow was composition, which was inheritance, which way the dependencies flowed etc. UML pictures made it easy to design modular software - just make sure all the arrows point in roughly the same direction and you're set.
When the UML scene began all this "enterprise architect" MDA bullcrap, as this article elegantly describes, it got thrown out en masse. Rightfully so, but with the bathwater we also lost this industry-wide capability to draw software.
Text is great, and in parallel with UML's demise, the industry got amazing at succinct technical writing: the README.md in a github repo. But sometimes a picture really is worth a thousand words and I still miss it.
This is my sentiment exactly. Now in it’s place we have bespoke diagrams where the meaning of lines, arrows and their directions vary from person to person and you need to ask the author to explain their convention before you can understand the diagram without assumptions.
At its core, MDA is just the notion that UML (or some other graphical notation, for that matter) should be able to express Domain Specific Languages (DSL's).
It's not clear that conversion from a high-level model to a platform-specific one should be a standardization concern, and maybe that's the "enterprise craziness" part that ultimately failed. But rigorously defined DSL's are not crazy; if anything, they're the only kind of "low code" that makes any sense at all.
> Text is great, and in parallel with UML's demise, the industry got amazing at succinct technical writing: the README.md in a github repo. But sometimes a picture really is worth a thousand words and I still miss it.
I think the decline in UML started with the decline of Waterfall as more teams adopted Agile. To state it more generally, more teams adopted ways of working that had shorter feedback cycles (relative to Waterfall) and unfortunately UML diagrams get in the way of that since they are not testable or easily made into prototypes [1] that can be shown to the customer for quick feedback.
1: That didn't stop people from trying. Enterprise Architect from Sparx Systems readily comes to mind https://sparxsystems.com/
A former colleague of mine held an opinion which I still strongly agree with, that the most productive use of these diagrams was during conversation, on a whiteboard. ( https://www.websequencediagrams.com/ is the next best thing)
I was in university 2004 to 2009. We had a total of 3 UML classes. A whole semester of wasted time. The professor that pushed this got "promoted" to a non teaching role after us. Everyone with some programming experience saw UML as a complete waste of time. The people pushing it at the time had no actual use-case just pie in the sky dreams of autogenerated software. It was doomed to fail.
Documentation in general got the knife in the back. This has nothing to do with UML I believe. The cost for refactoring pure software is very low so any mistake can quickly be corrected.
I would still insist UML be taught at universities just to open the mind of the students to possibilities.
For other industries which include hardware and software which has a relationship between mistakes and high costs, then it is obvious that any documentation technique should be used to lower the cost.
I used it a bit when it was still built into Visual Studio. You could even let VS generate some boilerplate class definitions, but it was never accurate and complete enough to use.
Frankly, for a lot of systems some block diagrams and some notes on the relations between them suffice instead of a full class diagram. I do like to use the sequence diagram though for complex communications between systems.
did anything succeed UML without the bloat and problems? I liked UML in principle but it just never was very useful to me beyond drawing boxes and arrows and the occasional sequence diagram.
I've drawn up UML (or close-to-UML) class diagrams in the past while trying to understand large, unfamiliar C++ codebases while new to a project. While they were painful to make (especially by hand), they provided a nice map that could be pointed to while asking questions in meetings with those who knew the code. The making of the diagrams were an exercise that definitely gave me a better understanding of the class relationships that I would have taken longer to learn otherwise. Beyond the initial exercise, I didn't find them very useful in the longer term.
I wish that the lessons from UML would one day lead to the a less ambitious modeling toolkit. What we need are ways to _communicate_ our design, not automate it.
While comments in code/tests, README.md etc. are a good way to explain the bits and pieces of our software, companies have various stakeholders (software engineers included) that can't affored the time to translate these primitive documentation formats so that they make sense.
Visual representation works the best, and I wish that UML would be elaborated as a sketching mean to communicate better with stakeholders, rather than being a part of an ambitious software-generation ecosystem.
There's a place for UML in the README.md; as some other commenters have pointed out, UML works much better as a sketching tool than as a total definition of a software system. A couple of quick class diagrams at the top level (probably generated using something like https://plantuml.com/) might provide a better communication model than text.
Yes plantuml is still my go-to visual design tool, whenever I feel information is missing, and I actually prefer it over mermaid (which has been integrated in github markdown), which I found very lacking.
What I like about text-based tools like plantuml/mermaid is the ability to see diffs in PR.
Other industry modeling tool use binary databases to represent the UML model and make it harder (i.e. need to use their specific diff visualizers, if available) to review changes of the design.
Maybe plantuml should be adopted and maintained. Unfortunately it is still stuck in a Java implementation...
You can still use UML for sketching. The free Doxygen tool even supports reverse engineering of UML class diagrams from (possibly annotated) source code.
On a side note: Why are there almost no VIEWERS for Markdown? Every project has a readme.md, which everyone ends up reading in a text viewer with all the formatting markers all over the place. WTF?
I'm working in a project that uses SysML, an extension of the ISO standards group that originally developed it. There are problems in that none of the tools for it are compatible with each other but it works if everyone uses the same one.
I'm also looking at whether QVT will work for doing transformations between models.
An open source tool is also desperately needed imo.
I kind of like SysML, but where I've seen it on a large scale it has failed spectacularly. People spend their time trying to figure out how to model things and fiddling with the diagrams to make them look nice. Distributed work is hard because merging becomes unintuitive. I think it could work if one really committed and tried to figure out all the edge cases, but the types of people pushing it at my shop have never been interested in that.
Personally I tend to just use the SysML package for Visio and draw "SysML inspired" diagrams these days.
My view on SysMLv1 is that domain-specific modelling techniques or tools are almost always far superior, and SysMLv1 therefore becomes a burden as you have to use the other techniques or tools anyway, and SysMLv1 doesn't have much to offer on top.
SysMLv2[1], which is work in progress, is more interesting because it separates itself from general domain-specific modelling techniques and tools by:
* Allowing definition of requirements
* Allowing modelling and checking of constraints/assertions
* Allowing modelling and execution of verification methods
* Allowing trade-off analysis where objects are instantiated differently to assess impacts
* Having the concept of concurrent/parallel states
* Having spatial, time and units concepts built in
* Allowing modelling with event triggers (e.g. when X happens, then the object's Y property increases by Z)
Graphical notations are still there but I doubt they will get much use. Instead, SysMLv2 introduces textual notations and I would expect this becomes the easiest notation to communicate with. Even for Object Process Methodology (OPM) which is frequently touted as being one of the better general purpose graphical (with parallel textual) modelling notations for readability, I always look at at the textual representation as it is easier to understand.
I think the intent is that SysMLv2 would allow you to specify requirements such as (completely made up scenario):
* [Site X] shall be located at [coordinates X]."
* [Site Y] shall be located at [coordinates Y]."
* A minimum of 15 [sites] shall be located in [territory X]."
* "Each [site] shall have a [line of sight path] to two or more other [sites]."
* "[Line of sight paths] between [sites] shall be calculated using [XYZ:2022 standard]."
* "Each [line of sight path] shall not exceed a length of 50000m."
* "For each [site] located in [territory X], [planning overlay X] shall not overlap."
* "For each [site] located in [territory Y], [planning overlay Y] shall not overlap."
* "Each [site] shall have a [chance of flooding] not exceeding {some metric}."
* "[Chance of flooding] for sites shall be calculated using [XYZ:2022 standard]."
You can then write many of these requirements as constraints/assertions in the textual notation and embed other languages within the SysMLv2 textual notation or call external software tools so that constraints/assertions can be calculated externally with external data, for example, GIS tools and data or historical records.
My main problem with UML is that it actually makes most sense in selective sketches rather than exhaustive blueprints and if you creating a informal sketch the details of the diagram syntax are pretty much irrelevant.
Why is that a problem? You don't have to use all of a programming language for it to be useful. UML is just trying to "unify" a bunch of useful diagramming under a common umbrella.
I agree with you and Fowler, sketches are probably a better use. When UML came about I think designs were largely developed before hand by architects/analysts and astronauts and given to developers to implement as is, but now they are better used to aid in documentation or spec out specific interactions/concepts that belong to a larger system.
Its not a problem for developers but arguably a problem with anything like UML - which perhaps explains why it has failed to really take off in the way that a lot of people 20 years agoreally expected.
Agree. The UML should only quickly explain the general idea, not the details.
Because the details get quickly outdated, since nobody will bother to update that UML everytime the code changes. And because if it's too complex, I could as well just read the code.
UML problem was cultural too. It's a crowd who valued too much heavy tooling (if not bloat). The more, the better (just like early java days)
Graphs are naturally useful, but UML quickly became a bad investment.
That said it was a time where projects were larger and communication was harder so the emphasis on large diagrams was probably enough of an improvement over potential chaos.
UML could've been much more popular and useful. In the early/mid '90s, I worked on commercial full-cycle CASE tools for mil/aero/datacomm development, including a "meta-meta-model" to support that. (Sadly, I loved my engineering and R&D teams, but business realities of the larger company happened repeatedly, and many innovative products and teams disappeared.)
Later, in grad school, writing various software in Java, and no longer working for a CASE company, but having many methodologies up the wazoo, I wanted a way I could rapidly iterate between static object model diagrams and the code. With no good CASE solution available for that, and no time to solve CASE properly, I forgot about all my hard approaches to the hard problems, and just quickly kludged up something that did "80%" of what I wanted, with "0.000020%" of the effort. I used OMTool from Rumbaugh's GE ACC group for the diagram editing, and wrote a code generator in Emacs Lisp. https://www.neilvandyke.org/jomtool/
My feeling is that its decline was at the expense of the IDEs and another developer-centric tooling (not in the early days open source, but latterly), and not a bad thing. Too often the tools became the focus at the expense of both less abstracted solutions and the real business problem.
In a related field, process frameworks are today’s version of that problem.
I the early 2000s as a consultant I had the job of designing and building a new e-commerce site on top of an existing green screen system. Java was an obvious choice and I found a tool to design UML diagrams which would spit out Java code with empty methods. Some of the developers were new to Java but these templates kept everyone on course. Worked like a dream.
> [10] Astonishingly, people in the small UML community associated my name with QVT for years afterwards. Though not always. In about 2012, I remember an important Professor who heard me mention QVT explain to me what the text actually meant — quoting text at me which I had written, and which did not mean what they thought it meant! I tried not to laugh.
Like the story of the novelist who sat in on a university lecture on their book.
In spite of all the hate against formal models, most of the problems I have encountered in the last twenty years are much easier to solve when the problem-solving conversation uses a model as common object. Conceptual data model (I love Merise), process with swimlanes, state machines... Nothing new and still extremely useful.
About UML specifically, I never understood the fixation on object orientation: the world looks relational to me !
Some random observations from an old-timer developer.
1. This excellent article is all about UML's class modeling capabilities. UML has other useful capabilities.
2. Sequence diagrams are very useful. I've created plenty to document and teach complex interactions between various (micro-) services. But it simply never occurred to me that I would generate code from sequence diagrams. They're simply a way to capture and refine the stuff on a whiteboard.
3. The data-modeling tools supporting logical and physical models suffered from some of the same needless complexity as the attempts to codegen from UML. And from the ludicrous expense of the tools. Every place I worked had at most one license for those tools.
5. The code-navigation and code-completion features in modern IDEs implement some of the best parts of the UML codegen vision. Tell VS that a class implements a particular interface, and it offers to generate a skeleton of the necessary methods for you. Great. Look at a method declaration, and see at a glance that it's from a superclass. Also great.
6. I hope somebody, maybe the author, collects articles like this for a text to be used in software engineering teaching. Our trade needs some serious mid-career training. The military has the Army War College. We need the Software Wars College, to get a chance to think this stuff through.
7. PlantUML is a pretty good way of embedding UML in wikis and other online docs. "Pretty good" is good enough for most purposes.
> 2. Sequence diagrams are very useful. I've created plenty to document and teach complex interactions between various (micro-) services.
I've always used the classic "bus timing diagram"[0] style of sequence diagramming. It's limited, but an excellent way to illustrate a parallel sequence.
I love sequence diagrams. They are essential for designing complex event-driven system where there are a lot of asynchronous operations. I often use them to make sense of and/or prevent race conditions.
I can also see the value in UML class diagrams for complex OOP systems but for me personally, I can make do without them in the vast majority of cases. They are not as valuable to me as sequence diagrams.
I still willingly make sequence diagrams to fully document what is happening in a complex system or architecture. I find them to be very useful to get everybody on the same page for the "order of events".
The class diagrams were something I was taught heavily in college and haven't really used since then. Feels like it's just as easy to write down "this object has a one-to-many relationship to this object"
Sequence diagrams force you to think about the flow of control in a system.
When reviewing draft designs, I sometimes ask the author to convert a simple boxes-and-lines architecture diagram to a sequence diagram. It can be revealing.
I can relate. It's an essential communication tool. When discussing asynchronous events with a colleague, there is a point in the discussion when it becomes almost impossible to explain it in words and you really need something like a sequence diagram to communicate accurately.
After reading this, and having minimal exposure to UML even during the late 90s and early 2000s, it strikes me just how many acronyms are needed to describe the ecosystem around UML. Perhaps the requirement of so much institutional knowledge led to its fall? I see correlation in that regard with web development today.
246 comments
[ 3.2 ms ] story [ 244 ms ] threadYes, I could create a class diagram as a PIM; press a button and create a PSM; and press another button and generate Java code. But the Java code had all sorts of holes in it that I had to fill in — and if I changed the model in any way, half of the code I'd written would no longer compile, let alone run correctly. In other words, OptimalJ automated the most trivial things, leaving all the hard work to the end user.
Unfortunately while MDA died, this same scheme is dominant today for OpenAPI definitions with exactly the same problems.
the teacher concluded the course with: "and this is UML, there is a high chance you will never see or use it again."
he was wrong, saw it a few times again.
he was right, never used it again.
Sadly, again and again, it is all destroyed by the client-facing people: "guys, the clients cant see the button can you make it yellow" and its infinite never ending variations, which make our job more akin to a jeweller because no amount of pre-code rationalization will prevent post-production resculpting.
Most expensive maybe, but "bravest" is surely something like spreadsheets or HTML.
It was a descriptive language, somehow useful to do nice charts, but the tools themselves were so bad the only reason devs used them is because of suspicious relationships between management and UML tool vendors...
> which make our job more akin to a jeweller because no amount of pre-code rationalization will prevent post-production resculpting.
Can I borrow that quote for my professional communications? This is so elegantly formulated.
Mind you - as most people using activity diagrams have never heard of Petri Nets they were a bit vague about what forks and joins actually mean and were using them as convenient ways to join multiple arrows together....
At one point I was making an object loader and didn't understand what hashmaps and hashtables were. I was making mistakes, debugging constantly and the complexity grew over my head.
I sketched out a quick 'n dirty class diagram and how everything related. Whenever I got stuck or confused, I'd look at the class diagram. I'd see where I was and noted to myself what I already implemented and what still needed to be implemented. I also asked myself if I was stuck with a high level (UML) issue or more a low level issue (not understanding a certain datastructure).
That class diagram was my rock and emotional support in coding up that object loader. So UML does have its place: if it gets too complex, but you know the design, draw out a UML-like diagram (or other diagramming methods) and it'll allow you to not have the high level picture in mind: it's right behind you on the whiteboard.
Other than that, yea proper UML has never worked for me.
I don't see a lot of value in UML's standardizing +,-,#,~ as access specifiers, vs just using the relevant language keywords.
Generally, unless people are using CASE tools, I tend to see them draw non-conforming diagrams that just roughly resemble what the UML spec says, and that is almost always good enough.
Diagrams are good, but having to worry about N different type of arrow heads, if a line should be solid or dashed, semi-obscure access symbols, etc is not good. and strictly speaking if you are not concerned about those things you are not actually using UML.
The exception is that nobody can ever convince me that a UML-style usecase diagram is better than alternatives like user stories.
The problem was also that the prof was always modelling some accounting/business "problems" which we also had no idea/experience about. So it was about learning couple of things all at once with very fragmented information. It was a disaster of class, and turned me off out of both UML and OOP. The latter I'm still sour about.
It's too bound up with OOP, specifically C++ and Java. It is hard to represent entities that are not simple classes.
Things that are idiomatic (in 90s C++, cough) look very verbose. If you have a base class, a derived class, and an interface you have a lot of duplication. It makes things like polymorphism look needlessly complicated.
And finally, it is ugly and unintuitive. The inheritance arrow goes the wrong way. I know it is supposed to say "derived IS SUBCLASS OF base" and thus goes upwards, but in my mental model it is "you start with base, and then go to derived (get more specific)" so it should point down.
I want to know that action X will trigger N calls and those calls call service foo and bar, and that foo then calls out to its data store and eventually returns something and service bar calls services raz and quux and those each fist call a caching service before going to their data stores. All requests eventually return (in the happy path). Now, as a reviewer, I can quickly see what talks to what and why that call happens and I can ask more intelligent questions like what happens if a cache hit happens when the data store has been updated.
What do you prefer?
The fact that UML formalized them as a way to describe code tells you a lot about the standard's quality.
I tend to think of OOP as a way to rewrite 'if's now. When you have the same huge 'if' or 'switch' in a couple of places, you can usually rewrite it to use polymorphism, and it becomes clearer. But it is totally fine to use procedural or functional idioms most of the time.
I don't know the whole breadth of the actual standard UML, and I don't know anybody who does. When I say UML, I mean as practiced and not as written, and that means: Boxes for classes, methods below, various kinds of arrows that I have to look up. For sure there are good parts in the standard, but that is not really relevant here.
As the sibling comment says, sequence diagrams are usually more useful. Or state machine diagrams. Or a diagram showing data dependencies.
Without UML, such designs would be worse because they would be less documented: if you have a relatively concise class diagram in front of you it's easier to ponder about what each of the arrows and boxes means.
So in my mental model a derived class actively "points to" its base class. Likewise a child commit points to its parent/parents.
There's a high variability in that, especially when metaclasses get involved and inheritance is itself a protocol (and thus can be hooked into every which way).
I do agree with the rest of your comment though, to me it also makes a lot more sense for a derived class to point to its parent than the reverse.
That make sense - pretty much every language I've used that supports inheritance class definitions refer to the class (or classes) they extend rather than the other way about.
class Vehicle extendedBy Car, Truck
class Car
class Truck extendedBy Semi
class Semi
This would be almost as awesome as "comefrom"[1]
[1] https://en.wikipedia.org/wiki/COMEFROM
I want to see a graphical representation of my "business" entities, not a more verbose 2D representation of my source code.
I fully agree with UML being stuck in OO land, though, and I think that’s the actual problem. Lambdas don’t exist, or have to be verbosely represented as interfaces. Type-level programming doesn’t exist. Anything higher order is unrepresentable to begin with. You don’t have to use Haskell to run into those limits, modern C++ is enough, or Kotlin, or TypeScript. UML is basically useless if you’re doing anything more interesting than cranking out Java 1.4 era EJB boilerplate.
That is a high bar, I'm not sure if UML meets it (wouldn't know, don't use UML, not intuitive enough for me). But I think something like SQL's syntax meets it - nobody would design a language with that syntax in this day and age, experts have settled on not using garbled pseudo-English. The experts who think "VERB GLYPH ADPOSITION symbol" (ie, SELECT * FROM table) is the simplest way to represent relational algebra just don't exist. Anyone competent would use some other grammar.
Idiomatic is close.
Yes, the Command pattern is what I vaguely alluded to in my message. The thing is, using a lower-level representation in something that’s meant to be an abstraction of the actual code makes zero sense to me.
It seems to me UML shouldn't be dealing with this fine-grained level of detail. It seems like a wasteful effort. Either design high-level, or get down to actual programming.
Managers were overly fond of the class diagrams because they could understand them. And dividing work between programmers by class rather than by logical feature somehow made sense to them. I recall one manager spending way too much time arranging to print a huge UML diagram across multiple sheets of A4, taping it to the wall and then annotating it constantly by hand.
But knowing it can still be useful for simple sketches. Similarly dynamic dispatch is a really useful tool for particular cases when programming – used alongside other non-OO techniques. Our industry follows fads and fashions to an amazing extent but when things fall out of favour the baby goes out with the bathwater.
While saying "it isn't intuitive" is a bit of a simplification, I think there is something to the argument.
I wonder if that is the case. Many programming languages do seem intuitive in light of other programming languages and other formal notation like math. The ones that don't are the ones I struggle with more. If I'm reading a new language and I see an '=' I can assume either a comparison or assignment. If I see a '<', I can normally interpret it as less than. The more a language violates this, the less intuitive I consider it and the harder it is to read through it without familiarity. This even applies among non-intuitive paradigms. OOP isn't what I would consider intuitive out the box (but then is anything), but once you know two languages implementation of OOP you can measure a third language's implementation as being intuitive to the exist pattern or not.
My experience with UML is that it was wholly new. It was as intuitive as the first programming language a person would learn if they didn't know math notation, which given the rate new students to programming know math notation, is a level of unintuitive that even most programming languages wouldn't have even as a first time language. Add in that many are introduced it alongside OOP in general (at least that was my experience in college) and it is even less intuitive than that.
So to that extent, I think I can criticize it as being non-intuitive even with the comparison to programming languages.
Paradigms aren't supposed to be intuitive.
Anyway, "intuitive once you grasp the fundamental ideas" is normally called "idiomatic" in informatics. I will second the other comment on this thread pushing that term.
Absolutely nothing about computers is intuitive. The entire area of knowledge is composed of fundamental paradigms and their extensions. Those can be "simple" or "idiomatic", but intuition doesn't go anywhere near them.
From a code generation standpoint (e.g. cracking out EJB boilerplate), the concept of model-driven architecture is generally a flawed idea. Lack of lambda expressions isn't that significant in the face of ignoring the complexities of real systems.
I'm curious about the issues you've hit representing higher order types though - was this in a class-style diagram?
I cannot fathom developing software without UML. How can you even design a system without diagrams? It's simply impossible.
There isn't one software component that my multiple teams at Amazon have designed that didn't use some diagrams from UML. And I'm sure you can say the same for any team in any FAANG.
Sure we aren't gonna do a class diagram the vast majority of the time, but there will almost always be some component diagram, sequence diagram, activity diagram, etc.
Some of the parts of UML are dead because they're not a good time investment, especially when working in Agile (class diagrams), but I'd argue that 90% of the people that say they never used UML after school have used it without realizing.
Just look at this thread, 100% of the responses are saying that UML = Class diagram.
Yet look at all the massively successful software written without any UML.
I started my career in the early 2000s in a big company on a big industrial project where several generations of contractors had already had their hands in. UML, rational rose, auto-generation of code that you had to manually correct, CORBA, manual tests, proprietary tooling...
It would take weeks to onboard newcomers, have them create unix account managed by some IT people in India so they could have access to the license of the proprietary point and click software to manage all this.
I think it was a time where decisions on tools were made by managers in the procurement teams. Selecting technology based on what they heard while golfing with their buddies or depending on kick backs they would get from providers.
Sorry, a little bit of a rant but to this day it still irks me to think how unproductive we were because of obvious bad choices. There is a silver lining though because during those years I learned more than any moments of my career. It taught me all the things that you definitely should not do if you want to be able to produce something useful at a reasonable cost. And one of them was to rely on UML for anything more than informally communicating simple designs with local team members.
I wonder if the current crop of low code tools learned from the whole UML story. Any chance things will be better this time?
I'm hoping that the (somewhat-fine) distinction between no-code and low-code is made with the same problems in mind, that is, an acknowledgement that code is quite often the best way of expressing the behaviour of a system.
When the UML scene began all this "enterprise architect" MDA bullcrap, as this article elegantly describes, it got thrown out en masse. Rightfully so, but with the bathwater we also lost this industry-wide capability to draw software.
Text is great, and in parallel with UML's demise, the industry got amazing at succinct technical writing: the README.md in a github repo. But sometimes a picture really is worth a thousand words and I still miss it.
It's not clear that conversion from a high-level model to a platform-specific one should be a standardization concern, and maybe that's the "enterprise craziness" part that ultimately failed. But rigorously defined DSL's are not crazy; if anything, they're the only kind of "low code" that makes any sense at all.
I think the decline in UML started with the decline of Waterfall as more teams adopted Agile. To state it more generally, more teams adopted ways of working that had shorter feedback cycles (relative to Waterfall) and unfortunately UML diagrams get in the way of that since they are not testable or easily made into prototypes [1] that can be shown to the customer for quick feedback.
1: That didn't stop people from trying. Enterprise Architect from Sparx Systems readily comes to mind https://sparxsystems.com/
For other industries which include hardware and software which has a relationship between mistakes and high costs, then it is obvious that any documentation technique should be used to lower the cost.
Frankly, for a lot of systems some block diagrams and some notes on the relations between them suffice instead of a full class diagram. I do like to use the sequence diagram though for complex communications between systems.
While comments in code/tests, README.md etc. are a good way to explain the bits and pieces of our software, companies have various stakeholders (software engineers included) that can't affored the time to translate these primitive documentation formats so that they make sense.
Visual representation works the best, and I wish that UML would be elaborated as a sketching mean to communicate better with stakeholders, rather than being a part of an ambitious software-generation ecosystem.
What I like about text-based tools like plantuml/mermaid is the ability to see diffs in PR.
Other industry modeling tool use binary databases to represent the UML model and make it harder (i.e. need to use their specific diff visualizers, if available) to review changes of the design.
Maybe plantuml should be adopted and maintained. Unfortunately it is still stuck in a Java implementation...
IMO any kind of informal diagram helps. Even just some boxes with lines between them.
Does anybody have information why this shouldn't be the case?
I'm also looking at whether QVT will work for doing transformations between models.
I kind of like SysML, but where I've seen it on a large scale it has failed spectacularly. People spend their time trying to figure out how to model things and fiddling with the diagrams to make them look nice. Distributed work is hard because merging becomes unintuitive. I think it could work if one really committed and tried to figure out all the edge cases, but the types of people pushing it at my shop have never been interested in that.
Personally I tend to just use the SysML package for Visio and draw "SysML inspired" diagrams these days.
Our use case is to be able to create models, they are the deliverable. Merging is a problem for us too.
SysMLv2[1], which is work in progress, is more interesting because it separates itself from general domain-specific modelling techniques and tools by:
* Allowing definition of requirements
* Allowing modelling and checking of constraints/assertions
* Allowing modelling and execution of verification methods
* Allowing trade-off analysis where objects are instantiated differently to assess impacts
* Having the concept of concurrent/parallel states
* Having spatial, time and units concepts built in
* Allowing modelling with event triggers (e.g. when X happens, then the object's Y property increases by Z)
Graphical notations are still there but I doubt they will get much use. Instead, SysMLv2 introduces textual notations and I would expect this becomes the easiest notation to communicate with. Even for Object Process Methodology (OPM) which is frequently touted as being one of the better general purpose graphical (with parallel textual) modelling notations for readability, I always look at at the textual representation as it is easier to understand.
I think the intent is that SysMLv2 would allow you to specify requirements such as (completely made up scenario):
* [Site X] shall be located at [coordinates X]."
* [Site Y] shall be located at [coordinates Y]."
* A minimum of 15 [sites] shall be located in [territory X]."
* "Each [site] shall have a [line of sight path] to two or more other [sites]."
* "[Line of sight paths] between [sites] shall be calculated using [XYZ:2022 standard]."
* "Each [line of sight path] shall not exceed a length of 50000m."
* "For each [site] located in [territory X], [planning overlay X] shall not overlap."
* "For each [site] located in [territory Y], [planning overlay Y] shall not overlap."
* "Each [site] shall have a [chance of flooding] not exceeding {some metric}."
* "[Chance of flooding] for sites shall be calculated using [XYZ:2022 standard]."
You can then write many of these requirements as constraints/assertions in the textual notation and embed other languages within the SysMLv2 textual notation or call external software tools so that constraints/assertions can be calculated externally with external data, for example, GIS tools and data or historical records.
[1] https://raw.githubusercontent.com/Systems-Modeling/SysML-v2-...
Martin Fowler's take on this:
https://martinfowler.com/bliki/UmlAsSketch.html
I agree with you and Fowler, sketches are probably a better use. When UML came about I think designs were largely developed before hand by architects/analysts and astronauts and given to developers to implement as is, but now they are better used to aid in documentation or spec out specific interactions/concepts that belong to a larger system.
Because the details get quickly outdated, since nobody will bother to update that UML everytime the code changes. And because if it's too complex, I could as well just read the code.
Graphs are naturally useful, but UML quickly became a bad investment.
That said it was a time where projects were larger and communication was harder so the emphasis on large diagrams was probably enough of an improvement over potential chaos.
UML could've been much more popular and useful. In the early/mid '90s, I worked on commercial full-cycle CASE tools for mil/aero/datacomm development, including a "meta-meta-model" to support that. (Sadly, I loved my engineering and R&D teams, but business realities of the larger company happened repeatedly, and many innovative products and teams disappeared.)
Later, in grad school, writing various software in Java, and no longer working for a CASE company, but having many methodologies up the wazoo, I wanted a way I could rapidly iterate between static object model diagrams and the code. With no good CASE solution available for that, and no time to solve CASE properly, I forgot about all my hard approaches to the hard problems, and just quickly kludged up something that did "80%" of what I wanted, with "0.000020%" of the effort. I used OMTool from Rumbaugh's GE ACC group for the diagram editing, and wrote a code generator in Emacs Lisp. https://www.neilvandyke.org/jomtool/
My feeling is that its decline was at the expense of the IDEs and another developer-centric tooling (not in the early days open source, but latterly), and not a bad thing. Too often the tools became the focus at the expense of both less abstracted solutions and the real business problem.
In a related field, process frameworks are today’s version of that problem.
Like the story of the novelist who sat in on a university lecture on their book.
About UML specifically, I never understood the fixation on object orientation: the world looks relational to me !
1. This excellent article is all about UML's class modeling capabilities. UML has other useful capabilities.
2. Sequence diagrams are very useful. I've created plenty to document and teach complex interactions between various (micro-) services. But it simply never occurred to me that I would generate code from sequence diagrams. They're simply a way to capture and refine the stuff on a whiteboard.
3. The data-modeling tools supporting logical and physical models suffered from some of the same needless complexity as the attempts to codegen from UML. And from the ludicrous expense of the tools. Every place I worked had at most one license for those tools.
5. The code-navigation and code-completion features in modern IDEs implement some of the best parts of the UML codegen vision. Tell VS that a class implements a particular interface, and it offers to generate a skeleton of the necessary methods for you. Great. Look at a method declaration, and see at a glance that it's from a superclass. Also great.
6. I hope somebody, maybe the author, collects articles like this for a text to be used in software engineering teaching. Our trade needs some serious mid-career training. The military has the Army War College. We need the Software Wars College, to get a chance to think this stuff through.
7. PlantUML is a pretty good way of embedding UML in wikis and other online docs. "Pretty good" is good enough for most purposes.
I've always used the classic "bus timing diagram"[0] style of sequence diagramming. It's limited, but an excellent way to illustrate a parallel sequence.
[0] https://study.com/academy/lesson/bus-timing-diagrams-definit...
I can also see the value in UML class diagrams for complex OOP systems but for me personally, I can make do without them in the vast majority of cases. They are not as valuable to me as sequence diagrams.
The class diagrams were something I was taught heavily in college and haven't really used since then. Feels like it's just as easy to write down "this object has a one-to-many relationship to this object"
Sequence diagrams force you to think about the flow of control in a system.
When reviewing draft designs, I sometimes ask the author to convert a simple boxes-and-lines architecture diagram to a sequence diagram. It can be revealing.