avatarPretheesh Presannan

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

10455

Abstract

Mobile App </b>and <b>Web API</b>.</p><div id="9ff9"><pre>webapp -> webapi <span class="hljs-string">"Get Tasks\nAdd Task\nUpdate Task\nDelete Task\nMark Task as Done"</span> mobileapp -> webapi <span class="hljs-string">"Get Tasks\nAdd Task\nUpdate Task\nDelete Task\nMark Task as Done"</span></pre></div><p id="b7b7">They are exactly the same, however, because they are essentially duplicated as plain text in code, it would be very easy, especially on a much larger scale to call them different names or simply miss-type them etc. If that happened, then from a Architecture Model perspectives, especially if it was used in some kind of automation, they would be seen as different operations.</p><h2 id="df93">Interfaces</h2><p id="ce74">If we were to implement these relationships in code, then this is how it may have looked.</p><div id="6040"><pre><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IWebAPI</span> { <span class="hljs-function">IEnumerable<Task> <span class="hljs-title">GetTasks</span>()</span>; <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">AddTask</span>(<span class="hljs-params">Task task</span>)</span>; <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">UpdateTask</span>(<span class="hljs-params">Task task</span>)</span>; <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">DeleteTask</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> taskId</span>)</span>; <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">MarkTaskAsDone</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> taskId</span>)</span>; }

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WebApp</span> { <span class="hljs-keyword">private</span> IWebAPI _webapi;

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WebApp</span>(<span class="hljs-params">IWebAPI webapi</span>)</span> { _webapi = webapi; }

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ViewTasks</span>()</span> { <span class="hljs-keyword">var</span> tasks = _webapi.GetTasks(); ... }

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AddTask</span>(<span class="hljs-params">Task task</span>)</span> { _webapi.AddTask(task); }

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">UpdateTask</span>(<span class="hljs-params">Task task</span>)</span> { _webapi.UpdateTask(task); }

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DeleteTask</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> taskId</span>)</span> { _webapi.DeleteTask(taskId); }

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">MarkTaskAsDone</span>(<span class="hljs-params"><span class="hljs-built_in">int</span> taskId</span>)</span> { _webapi.MarkTaskAsDone(taskId); } }</pre></div><p id="b617">Notice how all operations of <b>IWebAPI</b> are defined explicitly and only once, and then they can be used by <b>Web App </b>and in theory by <b>Mobile App</b>.</p><p id="48aa">So, I started thinking, it would be great if Architecture Model allowed expressing the relationships between structures much like we do it in code that implements those relationships.</p><p id="85af">Imagine if Structurizr supported code like this</p><div id="1fca"><pre>workspace { model { toDoApp = softwareSystem <span class="hljs-string">"To Do App"</span> { database = container <span class="hljs-string">"Database"</span> { selecttasks = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Select Tasks"</span> inserttask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Insert Task"</span> updatetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Update Task"</span> deletetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Delete Task"</span> } webapi = container <span class="hljs-string">"Web API"</span> { gettasks = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Get Tasks"</span> { <span class="hljs-keyword">this</span> -> database.selecttasks } addtask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Add Task"</span> { <span class="hljs-keyword">this</span> -> database.inserttask } updatetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Update Task"</span> { <span class="hljs-keyword">this</span> -> database.updatetask } deletetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Delete Task"</span> { <span class="hljs-keyword">this</span> -> database.deletetask } marktaskasdone = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Mark Task as Done"</span> { <span class="hljs-keyword">this</span> -> database.updatetask } } mobileapp = container <span class="hljs-string">"Mobile App"</span> { wiewtasks = <span class="hljs-keyword">interface</span> <span class="hljs-string">"View Tasks"</span> { <span class="hljs-keyword">this</span> -> webapi.gettasks } addtask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Add Task"</span> { <span class="hljs-keyword">this</span> -> webapi.addtask } updatetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Update Task"</span> { <span class="hljs-keyword">this</span> -> webapi.updatetask } deletetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Delete Task"</span> { <span class="hljs-keyword">this</span> -> webapi.deletetask } marktaskasdone = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Mark Task as Done"</span> { <span class="hljs-keyword">this</span> -> webapi.marktaskasdone } } webapp = container <span class="hljs-string">"Web App"</span> { wiewtasks = <span class="hljs-keyword">interface</span> <span class="hljs-string">"View Tasks"</span> { <span class="hljs-keyword">this</span> -> webapi.gettasks } addtask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Add Task"</span> { <span class="hljs-keyword">this</span> -> webapi.addtask } updatetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Update Task"</span> { <span class="hljs-keyword">this</span> -> webapi.updatetask } deletetask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Delete Task"</span> { <span class="hljs-keyword">this</span> -> webapi.deletetask } marktaskasdone = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Mark Task as Done"</span> { <span class="hljs-keyword">this</span> -> webapi.marktaskasdone } } } }

views {
    container toDoApp {
        include *
        autolayout lr
    }
    theme default
}

}</pre></div><p id="cacd">This code has explicit definitions of all Interfaces in all Containers. It also expresses Relationships by showing which other interfaces are being used by each interface. This is very close to the actual code that would implement these relationships.</p><h2 id="e69b">Flows</h2><p id="5705">Going back to the code example, it’s very likely that the implementation of any given method would end up using multiple interfaces, and possibly have some logic/control flow, like the code example below.</p><div id="8e49"><pre><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AddTask</span>(<span class="hljs-params">Task task</span>)</span> { <span class="hljs-keyword">var</span> tasks = _webapi.GetTasks(); <span class="hljs-keyword">if</span> (!tasks.Any(x => x.Id == task.Id)) { _webapi.AddTask(task); } }</pre></div><p id="9fb7">So, how do we represent this in the Architecture Model? What if Structurizr supported the following code</p><div id="4a6b"><pre>addtask = <span class="hljs-keyword">interface</span> <span class="hljs-string">"Add Task"</span> { flows { flow { <span class="hljs-keyword">type</span> Use expression <span class="hljs-string">"webapi.gettasks"</span> } flow { <span class="hljs-keyword">type</span> If expression <span class="hljs-string">"Task does not exist"</span> flows { flow { <span class="hljs-keyword">type</span> Use expression <span class="hljs-string">"webapi.addtask"</span> } } } } }</pre></div><p id="4229">This would not only still allow to render C4 Model Diagrams, it would also allow to render Sequence Diagrams with alternative flows, which would make it very valuable, as now the logic behind each of the interfaces can be visualised.</p><p id="a5a6">However, Structurizr does not support any of the above, nor do any of the other Architecture as Code projects I looked at:</p><ul><li><a href="https:

Options

//github.com/lonely-lockley/archinsight">Archinsight</a></li><li><a href="https://github.com/finos-labs/architecture-as-code/tree/main/calm">FINOS Labs Common Architecture Language Model (CALM)</a></li><li><a href="https://github.com/dwmkerr/architecture-as-code">https://github.com/dwmkerr/architecture-as-code</a></li><li><a href="https://github.com/jsoconno/architectures">https://github.com/jsoconno/architectures</a> etc.</li></ul><h2 id="086a">C4InterFlow was born</h2><p id="ddec">So, I’ve decided to build my own — <b>C4InterFlow </b>(<b>C4 Inter</b>faces and <b>Flow</b>s).</p><p id="b74a">The core Vision for C4InterFlow is to <i>“Transform the landscape of <b>Application Architecture</b> by bridging the <b>gap </b>between <b>Architecture Model</b> and <b>Code</b>.”</i></p><p id="7c22">That is why C4InterFlow started as a framework focused on generating <b>Architecture as Code</b> (AaC) in C# from the <b>actual Software System’s </b>C#<b> source code</b>, and then using AaC to generate Diagrams for different viewpoints.</p><p id="5402">As the C4InterFlow Architecture as Code <b>C# DSL </b>matured, I’ve started thinking about adding support for other more widely adopted languages and notations for expressing Architecture as Code like <b>YAML </b>and <b>JSON</b>.</p><p id="abef">Here is how the ToDo App could be described using <b>C4InterFlow YAML DSL</b>.</p><div id="4673"><pre><span class="hljs-attr">ToDoAppExample:</span> <span class="hljs-attr">SoftwareSystems:</span> <span class="hljs-attr">ToDoApp:</span> <span class="hljs-attr">Containers:</span> <span class="hljs-attr">Database:</span> <span class="hljs-attr">Interfaces:</span> <span class="hljs-attr">SelectTasks:</span> {} <span class="hljs-attr">InsertTask:</span> {} <span class="hljs-attr">UpdateTask:</span> {} <span class="hljs-attr">DeleteTask:</span> {} <span class="hljs-attr">WebApi:</span> <span class="hljs-attr">Interfaces:</span> <span class="hljs-attr">GetTasks:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">Database.Interfaces.SelectTasks</span> <span class="hljs-attr">AddTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">Database.Interfaces.InsertTask</span> <span class="hljs-attr">UpdateTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">Database.Interfaces.UpdateTask</span> <span class="hljs-attr">DeleteTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">Database.Interfaces.DeleteTask</span> <span class="hljs-attr">MarkTaskAsDone:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">Database.Interfaces.UpdateTask</span> <span class="hljs-attr">MobileApp:</span> <span class="hljs-attr">Interfaces:</span> <span class="hljs-attr">ViewTasks:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.GetTasks</span> <span class="hljs-attr">AddTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.AddTask</span> <span class="hljs-attr">UpdateTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.UpdateTask</span> <span class="hljs-attr">DeleteTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.DeleteTask</span> <span class="hljs-attr">MarkTaskAsDone:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.MarkTaskAsDone</span> <span class="hljs-attr">WebApp:</span> <span class="hljs-attr">Interfaces:</span> <span class="hljs-attr">ViewTasks:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.GetTasks</span> <span class="hljs-attr">AddTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.AddTask</span> <span class="hljs-attr">UpdateTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.UpdateTask</span> <span class="hljs-attr">DeleteTask:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.DeleteTask</span> <span class="hljs-attr">MarkTaskAsDone:</span> <span class="hljs-attr">Flows:</span> <span class="hljs-bullet">-</span> <span class="hljs-attr">Type:</span> <span class="hljs-string">Use</span> <span class="hljs-attr">Expression:</span> <span class="hljs-string">WebApi.Interfaces.MarkTaskAsDone</span></pre></div><p id="e90e">This is how the C4 Model Container level diagram would look when rendered using <a href="https://github.com/SlavaVedernikov/C4InterFlow/wiki/Command-Line-Interface-(CLI)">C4InterFlow CLI</a> based on the above AaC</p><figure id="9241"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*NzbUfjjsvBe3SSuth1aljg.png"><figcaption></figcaption></figure><p id="edef">And here is how the Sequence diagram for <b>Mobile App</b>’s <b>Add Task</b> Interface would look (notice the alternative flow).</p><figure id="1710"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*vw55vTuDUJxveqGv7jjD3w.png"><figcaption></figcaption></figure><p id="0add">In fact, just by executing a single CLI command below we can get C4InterFlow to generate 174 diagrams of different <b>Types</b>, <b>Scopes </b>and <b>Levels of Details </b>covering a large number of Application Architecture Viewpoints.</p><div id="4db4"><pre>C4InterFlow.Cli draw-diagrams --interfaces <span class="hljs-string">"ToDoAppExample.SoftwareSystems..Containers..Interfaces.*"</span> --levels-of-details context container --aac-reader-strategy <span class="hljs-string">"C4InterFlow.Automation.Readers.YamlAaCReaderStrategy,C4InterFlow.Automation"</span> --aac-input-paths <span class="hljs-string">".\Diagrams"</span> --output-dir <span class="hljs-string">".\Architecture"</span> --formats png svg</pre></div><p id="9707">Have a look as the complete <a href="https://github.com/SlavaVedernikov/C4InterFlow/tree/master/Samples/ToDoApp">ToDo App Sample</a> where you can explore all the Diagrams.</p><h2 id="84ef">Conclusion</h2><p id="f506">Event though I’ve been working on <a href="https://github.com/SlavaVedernikov/C4InterFlow">C4InterFlow</a> for around 1.5 years, and despite the fact that it is already full of very powerful and in some cases unprecedented features, I still feel that I’m just at the very beginning of my journey to fully unleashing the power of Architecture Model as Code.</p><p id="8159">There are opportunities to connect <b>Application </b>Architecture with</p><ul><li><b>Business</b> Architecture (already partially supported by C4InterFlow with <b>Actors </b>and <b>Business Processes</b>)</li><li><b>Data </b>Architecture (also partially supported by C4InterFlow with <b>Entities</b>)</li><li><b>Infrastructure</b> Architecture with C4 Model <b>Deployment </b>Diagrams.</li></ul><p id="1676">Because Architecture as Code is essentially just text, it can be used to fine-tune LLMs and build AI-Powered Chatbots — <b>Enterprise Architecture Assistants</b> unique for every organisation. Imagine how empowered and productive everyone in your organisation can be with a tool that can answer any questions about your Systems, Business Processes, Data etc.</p><p id="b40f">What do you think..? Can this be a future of Enterprise Architecture?</p></article></body>

Making Sense Of Discipline

Discipline as an extension of surrendering the infantile will (not to strengthen it)

Photo by Vignesh Moorthy on Unsplash

I think one takes up discipline

when one is ready to relax their infantile will and expectations

They see that they are at life’s mercy

and might as well cooperate with nature’s way — the matured way

be it writing, learning, mental health, or anything at all

we do it to get better at getting out of the way

— prioritizing the natural way things can unfold.

This does not mean I take up any discipline

since it sounds very nice to the same infantile ego

to get things done quickly

to achieve my success before such and such age

or to improve the infant

or such infant fantasies

That is still glorifying “undiscipline”

If you take up discipline because it sounds like a great strategy to avoid seeing your unconscious commitment to the very infantile forces within you and hyperfocus to get shit done as you want — you aren’t shit disciplined.

Not that anyone’s infantile itchings go away straightaway

because, you know, I am now doing discipline— No.

As a matter of fact what we face initially

when we take up a discipline

are these infantile reactions.

So if we had truly understood the importance of discipline

If we are doing it as part of growing

— there is only one growth; nature’s way,

the other one is mere image building —

and not for image building

then mostly our first task would be to tolerate our itchings.

Not to think I earned the right to suppress the annoying itchings

because I do not have the patience to go in a natural way

then that totally misses the point of discipline.

We had taken up discipline without the slightest clue or because someone wrote or said something about it.

If I can’t tolerate seeing my own infantile reflexes

and so force to resist them and do the thing

and call it a victory for the day

then how the hell would that be discipline?

That is the same infant in a new cloth.

After all, one takes up discipline

so that he could afford to be patient

— to take it easy in its own time.

Otherwise, what is the point?

One takes up discipline out of love and respect.

Not for self-respect or self-esteem.

Respect for the larger picture or just reality — trusting life

to finally be ready to be at mercy of life— to stop being clever

and thus surrendering our infantile itchings.

If this isn’t the attitude for discipline to promote growth

as an extension of our readiness to grow

then I don’t know what it is.

“It is essential […] that discipline should not be practiced like a rule imposed on oneself from the outside, but that it becomes an expression of one’s own will; that it is felt as pleasant, and that one slowly accustoms oneself to a kind of behavior which one would eventually miss, if one stopped practicing it.”― Erich Fromm, The Art of Loving

“In philosophy if you aren’t moving at a snail’s pace you aren’t moving at all. ”― Iris Murdoch

Poetry
Creative Writing
Discipline
Meditation Notes
Pretheesh Presannan
Recommended from ReadMedium