(评论)
(comments)

原始链接: https://news.ycombinator.com/item?id=37974021

作者提到访问一个讨论软件系统设计新范例 C4 的链接,其中涉及到模块化和灵活性的转变。 他们认为,虽然当前的方法经常由于大量的依赖关系而导致复杂且丑陋的系统,但 UML 很难避免这个问题,因为 UML 严重依赖于详细而冗长的描述。 相反,作者建议从更广泛的功能描述开始,然后逐渐将其分解为更小的模块。 然而,尽管图表总体上很受欢迎并且易于采用,但它们仍然没有得到充分利用,而 UML 却被认为是一个糟糕的选择,因为它依赖于复杂的设计并且忽视了实际的考虑。 为了提高图表的理解和实用性,作者建议对所有内容进行标记并添加图例,但他承认即使是经验丰富的技术人员也可能无法清晰地理解图表。 虽然作者认为标签足以替代复杂而深奥的图表,但其他人主张坚持遵守既定标准以增强理解。 最后,作者强调图表必须不断发展以反映现实世界的限制和权衡,并提供超越美观和便利的实际好处。

相关文章

原文
Hacker News new | past | comments | ask | show | jobs | submit login
The C4 model for visualising software architecture (2017) (c4model.com)
249 points by thunderbong 21 hours ago | hide | past | favorite | 91 comments










> Ideally this diagram would be automatically generated using tooling...

The biggest problem I've seen with architecture diagrams is they fall out of sync with the code base. In my opinion, automatic generation of these diagrams is necessary. Otherwise, teams have no way to know whether the picture in front of them accurately represents the latest state of the system.



Diagrams are similar to textual documentation: You generally can’t auto-generate useful ones from code, unless the code has extra markup that specifies what to generate. Diagrams often present a specific perspective that emphasizes certain features while omitting others. You might have several diagrams for the same entity, each illustrating a different aspect or scenario.

The upshot is that diagrams have to be maintained in conjunction with the code and application architecture, just like textual documentation. There’s just no alternative to simply putting the work in, and making it a regular part of change management.



The correct solution is a synthesis: generate the boxes and arrows from code. Then let a human hide, move, and style those objects. When the code changes, the boxes and arrows will change, and perhaps the style will want to change, but at least the diagram will remain correct. This is precisely the distinction between semantic markup and css, btw. Implying that the html would be auto generated, the css would be hand crafted.


I would actually be really interested in a bi-directional workflow, such that I would also be able to perform system redesign by changing the diagram's connections - the tooling will then automatically update the interface and the tests such that I wouldn't be able to commit my changes until the implementation matches the diagram.


I realize this isn’t what you’re arguing for, but as a cautionary anecdote on this topic:

Paul alludes to it in his post about Healthcare.gov from the other day, but this was apparently one of the major parts of the failure there - endless lines of code generated from UML diagrams, making reading the code hard and things like “can we add a trace statement here” difficult.

Optimising for diagrams-as-source-of-truth has drawbacks for debugging and maintainability of the running code

https://www.pauladamsmith.com/blog/2023/10/the-10-year-anniv...



IMO the source code to aspects of the system that are best shown as graphs should be the graphs.


This requires a preset architecture standard that explains specifically what boxes and arrows are, and how boxes/arrows interact. Lots of software smears a logical box out over several folders in the code, sometimes even with entirely different names. I don't just mean people write non-cohesive code, I mean frameworks tend to prefer organisation by layer ("the views go in the view folder!") instead of organisation by module ("These things work and change together with a defined boundary").

You can have what you're asking for if you agree to a predefined architecture and everyone agrees to write code that way.



Check out https://schematix.com/video/?play=schematix-editing

Schematix generates diagrams (models) from code which can be entered via the web interface, or from a remote command line or scripts.

Diagrams are rendered on-the-fly from queries called "topological expressions" run against the model. The model must be updated as IT workers change the environment, but since diagrams are generated from code, they always reflect the most up to date information from the model.



This is how I use the tool the author created, Structurizr. I auto-generate the initial diagrams, then manually fix it to make it more readable. We then check-in the JSON workspace export into our git repo. The first two levels of the C4 model don't change regularly, so this isn't a frequent process to repeat.


Agreed. I experimented with autogenerating C4 diagrams from source a while back, but quickly abandoned the project when I realized that the output was inevitably the flowchart equivalent of

  bool mystery_func(int i) { // define a new function
    int x = (int)(i / 2);    // x is i divided by 2 and truncated
    int y = x * 2;           // y is twice x
    return y == i;           // return true if y == i
  }                          // end of function


Indeed, the documentation (diagrams/text with particular layout and formatting) should abstract a lot of what the code does. Otherwise, what's the point since the code is there for you to read.

In my experience, auto-generated documentation in general does a poor job.

That said, such automation is improving by virtue of better AI, that understands and cross translates people's languages and computer languages.



I use diagrams for two distinct use cases :

- planning/outlining a solution

- documenting/insight into the system

I disagree that second can't be autogenerated - I've used class diagrams, database schema diagrams etc. to visualize projects, a lot of the time over the documentation - precisely because I can trust the generated diagrams to reflect current state.

Documentation is nice for context but I'd take good visualisation tools over most documentation I've seen on projects I've worked on.

Tooling to connect/validate documentation against code is non-existent, in my world at least. Maybe LLMs can change that down the line - have PR review against docs run as a part of CI/CD pipeline.



> You generally can’t auto-generate useful [architecture diagrams] from code,

The question is: why is this the case?

IMNSHO, the reason is that we don't have a way to express architecture in or as code. Instead, we have to compile the actual architecture of the system into one that is expressible using the call/return architectural style that our programming languages support.

That's a lossy process.

When we can program with actual architectural connectors, auto-generating useful architectural diagrams becomes trivial.

https://objective.st



I don’t think that’s the problem. There are so many different ways to look at a system. An architectural diagram shows you how components connect. A procedural diagram shows you what steps a program takes. An entity diagram shows you the major high level entities you’ve selected into your system. I just don’t see how a single language can express all the detail. Maybe a new one can be invented but I don’t see how S expressions solve this (the link you posted don’t have any indication that any diagram generation is part of the language). Also, diagrams can be useful even if they have birotted because discrepancies are a good teaching tool - “why does this diagram say x but the code seems to do y” is a tracing opportunity, an opportunity to update the diagram, and highlights which engineers are paying attention.

Maybe if LLMs get sufficiently advanced they can generate this stuff more automatically with some minor prompting with the code as context, but I doubt it. Not until AI can actually start understanding sentiment from code.



> An architectural diagram shows you how components connect.

That's the one we're talking about here.

> A procedural diagram shows you what steps a program takes

Which is useful if the program is procedural.

> An entity diagram shows you the major high level entities you’ve selected into your system.

That's the top-level of your architectural diagram.

> I just don’t see how a single language can express all the detail.

When the program's architectural style is call/return, we can do this just fine. Using stepwise refinement we move up and down the abstraction ladder of our system and thus add/remove detail. No problem.

The problem is that most systems these days are not primarily call/return, but have to be programmed in call/return languages.

> I don’t see how S expressions solve this

I don't either, and have no idea what S expressions have to do with this.

> .... diagram generation is part of the language

It's not part of the language. But it's part of the frameworks, and when the abstractions of your language are architectural in nature, there is a very close correspondence between the code and the diagrams.

> ... discrepancies are a good teaching tool...

Yes, since the diagrams are generated, it's easy to keep older version around and generate new ones on-demand. Then you can check the differences visually, in code, or as the difference between code and diagram. Take your pick.

> Not until AI can actually start understanding sentiment from code.

Again, the point is that architecture is not actually "sentiment". It is structural. The fact that it looks like sentiment in practice is purely a side effect of our programming languages being incapable of encoding architecture in the general case.



> The question is: why is this the case?

Diagrams capture and represent abstract and/or high level concepts. Their goal is to provide a kind of mental map of how specific aspects of a project are organized in order to help developers form their mental models. This means placing the focus on key constructs and downplaying the importance or relevance of other components. There isn't an objective way to provide a one-to-one mapping between what bits of a software project are of critical importance to form mental models, and what bits are irrelevant.

> IMNSHO, the reason is that we don't have a way to express architecture in or as code.

Not true. We have more than plenty of ways to represent software architectures. That is trivial and a solved problem. So is mapping representations of software architectures to (some) source code, at least in the form of skeleton code. The problem lies in mapping software projects to a software architecture, even when the software project is clean and a textbook example of a very specific software architecture.



You are confusing “implement” and “express”

If the architecture were directly expressed in the code, mapping back would be trivial. It is not because we effectively compile the actual architecture in order to express it in code. Mapping back then becomes decompiling, with the added complications of architectural mismatch and manual compilation.



You can generate it from code.

Diagrams are a flat map of someone's subjective and structured, interpretation of the code architecture.

Words displayed on a computer screen must be developed into supporting subjective knowledge structures.. free from the usual objective mindset of engineering.

You have to go up to first order concepts to get it. The vast majority of (popular) programming culture generates more of the same. Everybody tries to paper over this truth with metadata and it metaphysically does not work.

Computers are capable of much more, they are politically limited down to a small subset of what's possible.



In my experience diagrams that are pedestrian enough to be automatically generated from the codebase don’t add much value


The code-model gap is why we don't have this.

You don't organize code the way you mentally model it in many projects, and nearly all languages lack a way to solve this. Annotating code is prone to the same issue as keeping a diagram up to date, and the same issue as keeping comments or documentation up to date.



> nearly all languages lack a way to solve this

The only thing I’ve seen that goes in this direction is Knuth’s literate programming. I’ve tried it. In its current form it’s still clumsy, lacks tool support and IMO doesn’t fully solve the problem of how to deal with documenting a changing piece of software yet. Knuth got his requirements correct on the first try; the rest of us aren’t so lucky.



On the contrary, I think auto docs are robbing the team of the ability to think in terms of the higher level of abstraction.

High level diagrams should be disposable and rapid to generate. They are as important for what they omit as for what they show.



Some problems are people or process problems and can’t always be waved away with tools. Sometimes the answer is to enforce growth of the professional discipline to update documentation alongside code changes.

A way I addressed this was to add a checklist item automatically to PRs, “did you review and update the docs?” And put the docs in the same repo so that a code change will have documentation updates in the same PR. It’s mostly worked but still relies on discipline.

It’s kind of interesting how hard this is for some. The code change is 5 mins. Testing is 20. Documentation is another 10. I’ve seen lots of people not want to do the testing and really not want to do the documentation.



Ive seen testing reluctantly tied to “they’ll make me change everything in code review, so why waste the effort yet”


Yeah. And it’s possible the process is defective if code review can result in that much change. Oftentimes people skip most of the design process. I’ve been guilty of this.

Reminds me of the army mantra, “slow is smooth. Smooth is fast.” Skipping or rushing design has never actually saved time in my experience. And I see veterans repeating this mistake over and over.



Why is it that compilers don't do this? They have a parse tree for how the sysmbols connect.

Would it not be appropriate to extend the compiler for visualising relationships between software components with zoom-in and zoom-out facilities. Zoom-in takes you to Assembly and zoom-out to the CTO.



I think what Adam Jacob is doing with system initiative addresses this, right off the get go.


I think comments like these are too parochial in scope. Note the first actual example here, which is the system context. In this example, it describes the relationships between a banking customer, an Internet banking system, a backend backend banking mainframe, and an e-mail server.

Yes, your software may explicitly model all of these system components and potentially you can generate a system model from the code, but that would an entirely wrong approach. As a sibling comment says, this system context view describes the real world, not your software. The code is supposed to conform to the model, not the other way around. If the implementation has drifted to not be in-sync with the model, there are a few reasons this may happen:

- The legal or regulatory landscape actually changed. In this case, yes, the code may be more up-to-date and you need to change the model.

- External components your organization doesn't directly control changed. In this case, also, it may be the model that is wrong.

- The model is right and your code needs to change. Maybe you are not correctly handling an external third-party API. Maybe you're not correctly meeting your customer's needs. In the worst case, maybe you're breaking a law.

I would also think the reality at something as expansive as a bank, there is no such thing as the codebase. You don't have a single product. You have the backend data store and transaction processing system. You have kiosk software for your ATMs. You have workstation software for your tellers. You have a public-facing website for your customers. You have a mobile app. You may have an entirely separate set of insurance products, investment products, and so on. You have internal management and accounting system for generating reports. Most likely all of these need to be separate system, at least because one temporally predates others. In part because a bank is formed by mergers, acquisitions, and divestments, so some products may have originally been part of a totally separate organization and some may be destined to be their own totally separate organizations. Strategically as a company, you can't afford to give up that level of financial agility by creating hard software-level couplings between your entire product suite.

So sure, at the level of any single component, you may be able to autogenerate a high-level architecture diagram. But at the level of the entire system, you can't. This is probably most clear and obvious with something like the DODAF: https://dodcio.defense.gov/Library/DoD-Architecture-Framewor...

These are much-maligned and for good reason. They're often incomprehensible. But to the extent you're trying to model something like the operation of a war campaign, you're now involving:

- C2 systems for multiple branches of the military

- ISR systems for those same branches

- Communications systems

- Operational capabilities of all of the various intelligence agencies and foreign allies you interoperate with

- Weapons systems

- Tablet terminal, man-pack, and in-vehicle devices for your forward tactical elements

All of these are software systems, but they're developed on different cadences, by separate contractors on separate contracts, with separate fiscal appropriations bills and lines of accounting. Nonetheless, there is still a need at the strategic level to model the entire system. In order for this system to have any hope of working, it needs to be based on specifications with the expectation being that implementations will conform to the spec, not the other way around. It's more like developing the Internet than developing a web app. You can't autogenerate a diagram of the Internet, at least not one with any authority, by pointing it at the code for a server, a browser, an endpoint networking stack, and the networking stacks for various appliances like core routers, and figuring out some way to link those together, especially given you'd have to cut across arbitrarily many programming languages and code styles.



> The biggest problem I've seen with architecture diagrams is they fall out of sync with the code base. In my opinion, automatic generation of these diagrams is necessary.

Architecture diagrams document how the software is expected to be organized. They represent the goal, not the current state. The code needs to comply with the diagram, and not the other way around.

The only scenario where it makes sense to generate diagrams from code is when we have people trying to onboard to a project that's not documented, and even then these diagrams are only generated once, polished to remove noise, and from that point onward serve as the reference.



So how would you expect to insight on whether the current code differs from the planned design documents? By always applying a lot of manual human labor?


This is not a trivial problem to solve. Some would say that one of the entire points of software engineering is to assure that the code meets the design spec. A more rigorous approach would be to encode your design as a bunch of linting rules that you could run against your codebase (IaC and all).

I'm pretty sure that auto generating a diagram from some code and then trying to work out if it's semantically equivalent to something that was hand drawn is not the answer though. For one thing, the code doesn't contain or implement every single important aspect of the design.



Yeah it's hard.

For http API design I like to start with an openapi spec then generate as much of the server and client library implementation from this as possible.

The spec gives a language/implementation agnostic way to describe what you're intending to build that's nicely diff-able over time, and you can generate a lot of the boilerplate that's easy to screw up in a way that's both compile time (static types) and runtime (parsing/validation of inputs & outputs) safe.

I can imagine a world where a similar approach could work for higher level architecture. It's pretty common to have a shared helm chart that (largely) defines each individual logical service in k8s environments.

Taken to the extreme you could provision your data stores, and network policies etc using this approach such that an individual services chart defines exactly what it depends on. Throw in some metadata fields for descriptions and you're well on the way to having something that could generate some useful diagrams / documentation.

Of course the issue with such helm charts is that if you make them flexible enough to suit everybody eventually you'll just reimplement the underlying APIs they are calling - perhaps some approach using direct introspection of k8s resources and cloud resources with a standardized set of metadata to group and describe relationships might be more feasible.

For the moment I'll probably stick to excalidraw



Sure, but there’s a whole dimension missing here.

Architecture is more than simply “what", it’s also "why". It binds the context to the requirements and the desired components

A diagram is not "the architecture", it’s simply a view on it, or a "projection of the model" as the c4 folk like to express it as.

I just find the idea that we should automate diagram production because diagrams are hard to keep up to date a little quaint, because you hardly ever need to update just a diagram when changing the architecture. So your actual problem is that your design documentation is hard to keep up to date, and that’s a process problem. Generating diagrams from code won’t save you there.



> So how would you expect to insight on whether the current code differs from the planned design documents?

Developers are expected to know what they are doing and how their software project is organized.

> By always applying a lot of manual human labor?

That "manual labor" has a name: software development.

Software only changes if developers submit changes. Changes are reviewed as part of code reviews.



In all projects that I’ve worked on the code was much too complex for a single developer to have even a surface level understanding of all of it, yet one is regularly required to change unfamiliar pieces.


> In all projects that I’ve worked on the code was much too complex for a single developer to have even a surface level understanding of all of it, yet one is regularly required to change unfamiliar pieces.

That sounds like a self-inflicted problem, caused by a team failing to develop and maintain their system following basic software engineering principles. I'm not sure how diagrams are relevant.



You can't really make complexity go away. It just get's moved about. Auto creating diagrams will either mean specifying a new code artifact that will need to be kept up to date, and or create dependencies that will themselves fall out of sink with the code base. Or they'll be really simplistic and useless.

I think the best way to document a system is to write doco and just specifyc the intent of the system. What was this thing meant to do. That context is really useful for contrasting with the use of the system in a prod environment.



I like C4. I'd previously discounted the "context" diagrams that inevitably show "User -{do their job}-> System-of-Record" as useless. Now I see the point.

I'm working through a new piece of system design for a complex system using C4 with our extended teams.

In drawing the top level this time around though I realized that b/c we have a semi-disconnected mobile app (aside from a web UI) we need to degrade certain behaviors gracefully if we don't have certain results yet, either b/c we're offline, or the backend is just slow for some reason.

That rippled down into the next layer of the system as a job queue, which then rippled into the UX, because we can now say definitively which parts of the system may take an unbounded amount of time to complete a request.

I'm sure we'd have gotten to this conclusion eventually but the analysis put the issue front and center.

All because I had to draw a picture with "Remote-User --{Mobile Stuff}--> Backend."

Also whichever tool you use is up to you. I just use draw.io for example with different tabs for each layer. As we elaborate on this at some point we'll break the lower layers out to their own files.



I've always been unsure where this stuff fits in. Do you make it before your system is built, when its unclear how where all the cards will fall? Or after your system is made and in production and all the warts of reality are present and your graph is not so nice and neat anymore. This seems like an architects picture of things. Close enough to give people the false confidence to think they understand things, but not close enough to be of use to anyone actually working in the salt mines.


I get the points about not needing a formalised system for diagrams, even if C4 is quite light touch in my opinion (I never go down to the code level).

However, I do have to credit structurizr, which outputs C4 diagrams, as a great productivity boost. One model producing multiple views at all specificities is fantastic compared to mermaid, plantuml, etc, where every diagram needs to be self contained and define and redefine the same components over and over. Branching off, editing the model, presenting ideas, has been a very successful workflow for me.



I’ve only tried structirizr briefly, but I found it too inflexible. No way to draw concepts that aren’t strictly part of C4. For example I wanted to encapsulate 2 components in a box to represent that they’re currently deployed as one service (not necessarily a good thing to do in absolute but would have helped my team to grok it better): impossible.

I do like the idea of describing architecture formally, but the lack of customizability of diagram output was too painful



Mermaid's definitely not well-suited for the amount of text and text formatting that C4 requires. You can do it, but you will be jumping through hoops, and the autolayout breaks down pretty quickly when the arrows between boxes get chatty.


True but the big selling point for mermaid is the github integration and you can audit the changes to the diagrams via git log -p


Plus one for structurizr. Its model driven approach makes it a lot easier to keep the diagrams consistent with the code: You describe the architecture, and structurizr renders the diagrams.


I dunno, I kind of subscribe to software architecture being like, a set of design decisions that guide the implementation. That's what (in my experience) most software architects do; lay down guidance and structure for the software engineers.

> The C4 model was created as a way to help software development teams describe and communicate software architecture, both during up-front design sessions and when retrospectively documenting an existing codebase.

> It's a way to create maps of your code, at various levels of detail, in the same way you would use something like Google Maps to zoom in and out of an area you are interested in.

This seems different.

I have no idea why you would refer to the a code diagram as your software architecture. That's literally the code level. How is that architectural?

It's like saying the circuit diagram in the plug should go on the house blueprint. "You should use automated tools for this" ... so, it's for documenting existing code bases at the per-function level?

How is that useful for architecting / designing / planning software?

That sounds like software structure to me, not software architecture.

Sure, a map of existing software that explains how it's structured sounds cool... but I dunno. Like, if you're talking about design patterns, you're not gonna give someone a function-by-function map of how to implement a singleton. They're not stupid. You'd tell them you think it should have a singleton (or repository, or whatever).

Software design is totally a thing, and this seems entirely reasonable for designing software.

...but software design and implementation and software architecture are not the same thing and they're not done by the same people, in my experience.

This feels more like... systems design, which a software architect would contribute advice to in the way that the systems were designed so they aligned with good software architecture principals.

Maybe I'm just being pedantic. /shrug



> I dunno, I kind of subscribe to software architecture being like, a set of design decisions that guide the implementation.

I think this is the one mandatory part of software architecture which is giving developers information to help them make their own design decisions without constantly deferring to the authority.

But the exact place where architecture ends and development starts varies a lot.

I like to think that architecture itself decides what is important from the architecture standpoint. If architecture decides a certain low level application detail is important, then it becomes an architecture detail.

In fact, in most organisation architecture controls at the very least some top level design like components, communication patterns, APIs and technology in use.

In some organisation architecture goes as far as individual classes. Not all classes, but maybe classes modelling the domain of the problem especially, if that model is used as a language for multiple project or even implemented as a shared artifact.

I think C4 is suitable for those organisations where architecture is concerned with more low level structure than just listing applications and their integration interfaces.



Interesting, as I kinda share also that there are lines to be drawn between software architecture, design and implementation (all three).

Much like in the real world building of real-estate for example, I see there are different roles between the architect vs the engineers vs. the foremen.

What do you draw the line? What concerns/areas are to be covered in each of these [arch vs design vs implem]?



Excellent points.

(also, not too pedantic)

(also, principals -> principles)



> I kind of subscribe to software architecture being like, a set of design decisions that guide the implementation

Do you mean software architecture is such as a set of design decisions? Or that software architecture is a set of design decisions?



In the 80s I learnt SSADM and it was great for making sure business logic and architecture were understood and viable before a line of code was run. Which was very important on old mainframes with several hour turnarounds on compiles.

For last few decades I have only used diagrams to design and to explain. Have found too hard to keep diagrams up to date when iterating on compiles multiple times per hour.

What I feel is needed is ways to keep code, infra and spec in sync throughout the lifecycle.



Even as a non civil engineer I can understand floor plans and alikes and find then immediately useful. Even as a professional SWE these example diagrams don't seem useful or informative enough to justify bothering with them.

Code is too multidimensional to be approximated with 2d drawings. It just doesn't work.

What could work are more conventional architectural code patterns. Things like structured concurrency, but also for higher level. Maybe.



Mostly because software architecture diagrams need a lot of context or have to be in specific context and quite tight scope.

Floor plan has really fixed context and very limited scope. Like I don't have to explain windows ... but in software most of the time you actually have to explain "window" because every "window" or element will be different, you cannot just say this is window and copy it 20x.



This is how you know software engineering is still an immature discipline. It’s 25+ years (in my case) as still we are having largely the same discussions about “basic” things. I’m not saying this is bad, but progress is slow, and we can’t blame any particular company or consortia or commercial interest here.


Honestly we have the same problem outside of engineering. C4 is really just a way to focus conversations along one level of abstraction.

How many times have you talked to someone who bounces up and down from high detail high complexity to zoomed-out simplicity in the same thought, and not understood what they wanted to tell you? We have the same issue when devs think "I will just yolo some boxes and arrows on this board, it makes sense in my head so it is a good diagram!"



C4 is very interesting and I think tackles certain problems related to software architecture really well. It sort of turns the lower levels of an architecture, which is mostly hardware and system software, into broad abstractions and focuses the effort on the stuff that sits above that in the stack. Which turns out to be surprisingly suitable for today's cloud-based/containerized scalable approaches.

Related, Archimate is also very good and there's a lot of overlap, but grounds itself more into the infrastructure bits. I've used some version of diagram approaches similar to Archimate in the past to really great effect to deconflict systems and data sources and demonstrate how all the stuff we're buying and gluing together supports specific business and user workflow needs.

Comments here about how this stuff all gets out of sync with the codebase are absolutely correct. But I've found that they can be excellent tools for use when you need to analyze a complex system or communicate systems and plans to a larger group.

It's surprising how often there isn't really any form of cohesive documentation and just sitting down for a couple weeks and drawing boxes with lines connecting them can unblock and simplify failing and frustrated efforts to move forward, especially when teams are working in the same playpen.

C4, Archimate, UML, whatever are really just good constrained diagramming languages you can use to capture specific things you wish to communicate, analyze, or memorialize. I think they aren't very good as preplanning and design tools.

Many of us suffered from the big UML push days where every facet of a system down to class definitions were supposed to be laid out in excruciating detail by some chief architect's office before a line of code was laid down. Madness like "we'll just generate the code from the diagrams" caused millions to suffer. When coding actually did start, those thousands of hours of planning usually were just ignored and the developers just did what they wanted anyways.



I've tried creating diagrams of this nature (not realizing this is a thing) but I chose them for documenting the system to others that weren't already familiar with the project so it felt necessary to layer it all together. Those diagrams shown looked more like team meetings hashing out the details. Seemed kind of an unfair comparison.

That being said, the biggest issue I ran into is in the diagram tooling. At the time we had Gliphy. One could not make it interactable, such that double-clicking on a node would explode the container and let someone drill-down. At best they had layers which were awfully crude to work with. And at the end of the day didn't export in SVG so were useless for embedding. Overall, a waste of time. :(



If you model software, both existing and future state, as a primary business and technology activity, modularize where needed, reduce high level abstractions, follow SOLID/DRY for the most part, and use bounded context operational data stores, the architectural diagrams serve a greater purpose and are a primary artifact.

In other words, no one should change code without first validating those changes with the existing model(s).



I like the model, and have had to use UML in security architecture where the whole thing hinges on consistency from the top level context to the code. The simplicty of this C4 model is a forcing function, where if there is hidden context or components, they have to shake out in the model. I'd suggest resistance to something this simple chould indicate there may be hidden elements (which there are more often than not on large projects). Forcing people to clarify their thinking into something like this decentralizes them by having them commit to statements and ideas instead of just reserving a right to suggest and criticize, and you can get a lot of resistance to that as well. These aren't model problems though, but they're what happens when models meet people.

I'll use something like this as a reference for security design as I really like its consistency.



If you find the C4 model to be too arbitrary and over-specified, I wrote on an alternative practice earlier this year: https://www.ilograph.com/blog/posts/concrete-diagramming-mod...


Mermaid supports C4 now [0]; though still experimental, it works in Notion and Github renderers.

[0] https://mermaid.js.org/syntax/c4.html



I think most visualizations suffer from identifying the wrong piece of complexity — the essential complexity is state management, not code management.

Ideally, we should be able to visualize state and how state changes. This isn’t a state machine, and it isn’t database modeling. It is an understanding of information flow. Sometimes this flow of information has real-world side-effects (moving a robot’s arm), but mostly this flow is about information being created, transformed, and delivered.

I use the word information because this decouples the visualization from concerns about data and modeling. The important thing is information, not necessarily the way we model that information — those kind of visualizations already exist and are helpful for writing code. But the kind of information flow visualization I’m imaging would help us to understand not how to write code, but what code that needs to be written in the first place.

The most complex pieces of code tend to be buggy when changes are made to them, because they are acting upon state in ways that are essentially complex and interdependent. Wouldn’t it be nice to know that when you update a person’s first name that is is actually affecting systems X, Y, and Z rather than merely systems A, B, and C? Maybe the credit card validation system utilizes the first name in some odd way that your profile page doesn’t, but how would you know that by looking at the code for the profile page? You wouldn’t.

An information flow visualization could potentially identify that. Or maybe not. People don’t usually reference visualizations or keep them updated. A visualization would have to be 10x more useful than they are today to become a routine part of the daily grind of software development, ideally built into the dev experience like IDE type errors are.

Imagine an analog to jumping to a function definition for a state usage — jumping to a visualization of the information you are about to put your dirty paws upon. I suppose this would require a many-to-many relationship between the information flow visualization and state (and anywhere that state was stored, accessed, or mutated).

Fun dream.



Related:

The C4 model for visualising software architecture - https://news.ycombinator.com/item?id=21032805 - Sept 2019 (59 comments)



I watched the talk on the site, and I liked it. But I also immediately had the question: Where do my actual abstractions live? So, not the concrete instances of an abstraction that runs somewhere, maybe as a component, maybe as code, maybe even as a whole container; but the abstraction itself.


You can see a crappy house that’s falling apart pretty easily. Conversely management cannot see a crappy codebase that’s rife with technical debt. Maybe they would make more intelligent decisions if they could visualize the problem.


Code quality does not seem to have any correlation with business success. Why should business care?


Well this is just wrong, so I don't really know how to respond. You're probably thinking about monopolies such as Facebook, Google, or the like, where not only does code quality not matter, but not much matters at all. Most businesses do not have this luxury.


Admittedly I'm a greybeard. Wrote my first app in 1984. Moved through the ranks, from support to dev roles, application architecture, enterprise architecture and finially process optimisation.

And so wow, those diagrams in the links - how does one even manage all those boxes?!?

Architecture is easier than coding, if you stay away from more/bigger/but_my_app_is_a_special_little_snowflake mantras. Consider the age-old, tried, tested, proven architecture models of yore (other than their most excellent diagram notations, stay away from UML).

Architecture (design) is layered, not spaghetti thrown at a wall, hoping something sticks. Most (99.9%) software domains can be divided into three horizontal layers -

1. UI

2. Application/business layer

3. Data layer

(note that both internal and external service layers sit at the same level as data layers, allowing them to be called from the application layer)

Finally, there are vertical layers (shared across the initial three layers) These typically include -

4. Communication

5. Exception management

6. Security

7. Logs

Start with that as an overview/index of the entire solution, and when the beast needs to grow, just grow it. But grow it wisely. Use the standard 3-tiered architecture model. Re-use those cross-cutting concens in new applications.

Federate identities. Standardise access/permissions management.

Finally, don't feel compelled to use all the things - if the solution is services-based, don't code a UI for it. Simply connect your client to the relevant, existing service. Yes, services can be tiered, assuming your management processes are mature.

As to the management issue. Governance is what keeps your estate from turning into a hairball. Make extensive and judicious use of

1. Risk management

2. Change management

3. Stakeholder management

4. Design reviews

5. Project review (where team members grade managers)

Establish a technical design authority. The TDA concerns itself with broadly technical matters that facilitate a system-wide perspective. This might include -

1. Systems and solutions

2. Data

3. Communications

4. Quality objectives, including security

5. Development and development operations (devops)

6. Infrastructure (including but not limited to directories; networks; servers, both on-site and remote/in clouds; workstations and mobile devices).

7. Testing (Tools, techniques, platforms, languages and frameworks)

8. Locations



Nice, thanks.


> Ask somebody in the building industry to visually communicate the architecture of a building and you'll be presented with site plans, floor plans, elevation views, cross-section views and detail drawings.

Well ask an architect to visually communicate “how the building is going to work”, ie, where do pilots go, how security works, how long will the waiting line be. What happnes to people missing the plane after they go through security. Then we’ll talk about those software diagrams.



The talk about programmatically creating these diagrams is interesting, but it would be more interesting to use this in reverse with AI. Create a C4 diagram with a GUI, programmatically factor it down to some kind of text-based format and use that as an input for a code-generating AI. Imagine rewriting vast chunks of code by just editing the structure diagram.


I've seen some cool results when asking GenAI (here it was ChatGPT) to create code based upon a sequence diagram and vice versa. The goal is to have an abstraction to generate code from. Or at least build the 80% of the text for something to be a seed for generating code.


To quote Jamie Hyneman: "When in doubt, C4".


Interesting but I don't think this especially adds anything. The high level diagrams are great but then you can already make those without having to read any fancy visual model websites. The site even kind of admits this:

> As an industry, we do have the Unified Modeling Language (UML), ArchiMate and SysML, but asking whether these provide an effective way to communicate software architecture is often irrelevant because many teams have already thrown them out in favour of much simpler "boxes and lines" diagrams.

This is very true, but then they seem to have ignored the reasons why UML class diagrams were a total failure. They somehow acknowledge that nobody likes them, but then the 4th C of their model (code) is... UML class diagrams!

You don't need this. Just do ad-hoc diagrams and make them clear, with labelled arrows. Their first three diagrams are actually good examples of this.



That's what I do. Boxes and lines between them. It helps a lot when thinking up new concepts and brainstorming too, so that the tool doesn't slow you down.

I use Freeform now, which is super simple but works. Mark two objects and cmd-click/right click, then click "add connecting line".



One step further: Powerpoint. Sooner or later the diagrams will usually be needed in a presentation. Having them in a presentable format saves another step, and is a constant reminder to produce something worth presenting.

Those diagrams that don't end up in presentations will be write-only anyway, and could be in any random format. No-one is going to read them.



That’s a really good point, I’ve had to redo diagrams before to fit them into a presentation, and because they were sprawling all over the place in Figma or Miro, they required extra work to fit correctly and be readable. Powerpoint or Google Slides forces you to concision and the aspect ratio of the slide, for good or bad.


Freeform is basically a simplified Keynote, which it is based on. I used Keynote before. Might actually return to it since Freeform is pretty basic right now (it's pretty new).


Is it Freeform as the Apple Freeform? I tried it last week to create high Level design, still not as smooth as I expected. Mainly the text editing flow feels not seamless yet, the deal breaker was I couldn't get the file successfully shared thru any available options.

To be fair it's still in its early of its time, I'll wait bit longer.



Apple Freeform yes, comes with macOS. Before that I used Keynote.


UML is still highly used at the architecture command deck, even if the dream to generate code from diagrams failed.

Just a couple of months ago I finalized yet another archictecture document, with enough class diagrams, sequence diagrams and use cases on it.



Try testing if people can comprehend the diagrams by asking a question after showing them a somewhat complicated one. You'll likely be disappointed. We don't seem to be using them because they work.


As it happens, most people understand easier a standard notation that can refer to, and get a book at the library, than NIH boxes and lines.

Now people straigth out of bootcamps calling themselves engineers, without having a Software Engineer degree, yeah maybe not.

Then again, they can get that book I just mentioned, and in the process maybe discover other goodies at the local library, or just ask ChatGPT.



I don't think the standard matters, so much as the visual diagraming not seeming to work well at scale.

A drawing showing the relationships between database tables seems to be comprehendible to people, until you get to over 7 tables or so, and then they don't appear to be able to make sense of it. Real databases often have magnitudes more tables than that.

You apparently have something you can do a trial with. Show it to people, give them time to digest, and politely quiz them a bit to see if it worked.



> As it happens, most people understand easier a standard notation that can refer to, and get a book at the library, than NIH boxes and lines.

I do not believe this for a second. You're possible arguing against a straw man.

The alternative to UML isn't a "NIH UML" which uses a different array of arrows. It's labelled boxes and lines. You don't need to go to a library to understand the diagram because the diagram is self-explanatory.

Here's a really good example:

https://buck2.build/docs/concepts/concept_map/

Every arrow is labelled. No tedious textbook needed.



You are free to believe in whatever makes you happy, I am not UML missionary.


Having structured architecture conventions becomes more important when you have many architecture conversations across multiple people and would like to gain insights from the diagrams too.


But you don't need and official standard that everyone learns. Just use words. If your box is a class, write "class Foo". If your arrow means "contains 1 or more" just write that next to the arrow.


Yes, that’s exactly the convention that C4 specifies: add legends on every diagram and make sure things are labeled in a way that people can understand.


Well they don't follow their own rules then because the "Level 4" diagram on that page is just standard awful UML with no legend or labels.


The same article posted for the 14th time since 2017. https://news.ycombinator.com/from?site=c4model.com








Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact



Search:
联系我们 contact @ memedata.com