Showing posts with label agile architecture. Show all posts
Showing posts with label agile architecture. Show all posts

Wednesday, July 30, 2025

Design versus Architecture in software development

First try (from Gemini 2.5 Flash)

Software architecture defines the system's fundamental structure, outlining its major components, their high-level relationships, and the overarching principles and quality attributes (like scalability or security) that guide its construction. It's the "what" and "why" of the system's foundational choices, which are costly to change.

In contrast, software design focuses on the detailed internal workings of individual components and modules, specifying their logic, data structures, and algorithms to implement the architectural vision effectively. It's the "how" of putting those foundational pieces together, generally with a lower cost of modification.

Second try (with my input)

Software architecture defines the system's fundamental structure, outlining its major components, their high-level relationships, and the overarching principles and quality attributes (like scalability or security) that guide its construction. It's the "what" and "why" of the system's foundational choices, which are costly to change and, by their nature, represent the unique, large-scale blueprint of a specific system, and are not directly composable with other architectures.

In contrast, software design focuses on the detailed internal workings of individual components and modules, specifying their logic, data structures, and algorithms to implement the architectural vision effectively. It's the "how" of putting those foundational pieces together, with decisions often leading to reusable and composable solutions that can be combined to build larger features or even integrated into different systems.

Why the difference (Gemini):

My answer was a reflection of common knowledge, while your insight stemmed from highly specialized and deep expertise in higher-order functional programming.

Some remarks:

  • Architecture is often brought in from external sources, less often developed.
  • Architecture is an expensive risk: a bad architecture can doom a project, a poor architecture can explode your costs.
  • A team that does not master their architecture and designs is a big risk, and not all teams have the skills needed for chosen architectures and designs.
  • Design fits in an agile process. Architecture is often hard to fit in an agile process.

All original content copyright James Litsios, 2025.

Saturday, November 09, 2024

Why the struggle with functional programming?

Slow FP adoption...

Why no widespread adoption even though functional programming exists already now for over sixty years?

Not so long ago I explained this as:

The reason is actually pretty complicated: The strength of FP is much due to its ability to be very strong. This strength in the code weakens the ability of developers to make local changes. Initially, this sounds like something good, yet it creates a new challenge: developers are bound to the constraints of code written by others, and they are not only not happy, they are less productive! You can solve this by bringing your FP to the next level: math. A few companies do this, now a developer is not subject to constraints but to mathematics. If the developer understands the math she/he finds this acceptable.
I am simplifying things a bit here, yet FP, or any language that is strong enough, brings in a whole complexity of technical ownership and people dynamics that does not need to be dealt with with OO. The reality is that FP allows more scaling, but maintaining the stability of people within that scaling is a major challenge.

I want to present this a bit differently here, because the above put too much blame on people. Yes, FP is tricky for teams, yet the root cause is not the teams, the teams just highlight the root cause!

The Design - Features - Tasks trilemma

Let's start with the following trilemma

Design - Features - Tasks

And by trilemma, I mean that you cannot simultaneous set goals to progress all three. (And by task, I mean "effective coding work"). You must specify two of these, and let the third one be determined by the outcome of your work. You can specify design and features, you can specific design and tasks, you can specify features and tasks... but you cannot specify design, features, and tasks before you start working.  To be more concrete: when you focus on architecture before coding, and come up with a design, you are in fact constraining the features that will be implementable with tasks that follow that design. If now you specify additional features, before you start your tasks using the given design, you will likely fail.

Functional programming done seriously "ties" design and tasks together. By which I mean that FP that pushes its higher order design model highly constrains the design. The result is that by construction, a team that pushes its FP design culture, is also a team that is "squeezing themselves" into an over constrained design-features-tasks trilemma. To be specific, an FP team may be imposing design, features and tasks all at the same time, and not understand that this is an over-constrained setup that will most often fail.

There is a solution: Just like I mentioned in that earlier post, you get a around trilemma by splitting one of its terms. Here we split tasks into design tasks and non-design tasks. The approach is then the following:

  1. Given some desired features
  2. Work on design-tasks so that the design can implement the features
  3. Then work on non-design-tasks, that implement the features with the developed design.

From a work triplet perspective, we have:

  1. features & design-tasks -> new-design
  2. features, non-design-tasks -> implemented features

Here, the new-design produced by 1, are used in 2.

However, the challenge is that now we have a two phase work process, and by default teams, especially agile teams, are single phase process. Agile typically asks teams to focus on tasks that deliver MVP features, and therefore agile typically sets people up to fail, as there is no new feature in good FP without new design, and... and teams often struggles to juggle the three needs to progress design, features and tasks within a same agile effort.

TDD helps

Test driven development (TDD) is one way to escape the limits of a one phase agile process. The idea is the following: 

  1. Given some design features
  2. Develop tests for these features, AND extend the design to cover the features.
  3. Then work on non-design-tasks, that implement the tasks, and pass the tests.

However...

Yet there is still a challenge: design changes most often depend on strong opinions. FP depends on design changes. FP depends on strong opinions. Getting teams to gel around strong opinions is often not trivial. And that why I wrote the statement shared above.

All original content copyright James Litsios, 2024.

Monday, December 19, 2022

Managing agile from technology to business

 This how I tend to look at management ownership in agile development (see previous blog entry for more on the alternate views of agile):

Where:
  • The CTO owns technology and most often engineering teams.
  • The Engineering Manager may be an inwards looking CTO and also own technology and engineering teams, but is often less owning technology and more owning agile processes and engineering teams.
  • The Product Owner owns the team's product vision and possibly the customer strategy. She/he is a member of the development team or has a representative that is part of the development team.
  • The Technical Product Owner owns the customer view of technology, may be a full fledged product owner, or may be a support member of a larger product owner team.
Individuals become more and more key enablers as your product and technology base become more advanced. A Servant Leader is then a manager (e.g. engineering manager) that helps individuals contribute in independence yet within orchestrated flows. This figure illustrates where the servant leader provides critical guidance (the red corners!):
Here, from the central diagonal outwards:
  • The team iterates a technology and product development and review cycle, again, and again.
  • In parallel, the team learns and explores productivity and innovation. Product does the same with their customers and market segment.
  • Productivity issues are monitored. In a physical model of agile processes 'high momentum' is high productivity. Servant Leaders help monitor for issues such as unsustainability, diverging focus, low or over capacity, and help teams and product avoid or resolve these issues.
 My experience is:
  • Product Owner and CTO have too much "skin in the game" to be effective servant leaders. Therefore engineering managers and technical product owners (when they have only partial ownership) have a critical servant leader role to play to help all deliver better.
All original content copyright James Litsios, 2022.

Sunday, December 18, 2022

Agile from business to technology

This is how I scale agile towards business and towards technology.:



Where:
  • In the center we have an agile process that blends team process and product process.
  • To the right we have a business process that ties into the product process.
  • To the left we have a technology process (expertise process to be general) that ties into the team process.
To be honest, this is my minimal theoretical business to technology agile process. In practice, a specific agile process is chosen, with process steps and process artefacts. People like to say that agile is about people, not process. Yet people need to communicate, and the common vocabulary for that is given by a process.

Deepening in to the product business view (right side above):


Where:
  • The core agile process (blue) delivers features and deliverables that are part of a product and business goals.
  • These deliverables are picked-up by customers
  • The features and deliverable sustain (or not) the customers competitivity within its market segment
  • The product owner (in scrum terminology) is the expert that guides the product with regards to the customer needs.
We can do that also for technology/engineering (left above):


Where:
  • The core agile process (blue) includes experts within the team.
  • The experts enable/produce the technical/engineering needs of the features and deliverables.
  • The expert individuals may be experts in different domains.
  • Coordinating technology/engineering frameworks allow experts to work both as individuals and in coordination (within their team).
Many domains of technical expertise are possible. Above are the ones closer to my experience.

Note:
  • The complete process above needs to coordinate at least SIX streams.
    A minimal agile process only presents three streams (team vs product vs customer). 
  • Each of these (six) streams will naturally be driven at their own different rate!
  • Your job, as CTO / engineering lead is to work with individuals, teams and product to pace work within these different streams to achieve an optimal throughput!
    •  Think laminar flow! Productive is as fast as you can go before things become turbulent!
I wrote this up as a (much longer) slide deck, and am always happy to share my experiences!

All original content copyright James Litsios, 2022. 

Sunday, April 12, 2020

Thinking versus brute force "doing" in software design in 2020

About thinking versus doing

(I put a subset of this on YouTube as: https://www.youtube.com/watch?v=_kXpyctbmrQ)

Is it ok to program by "brute force" and put aside your brain?

A few years ago, I wrote on the pros and cons of programming with explicit and implicit type declarations. In 2020, I feel that this question is almost irrelevant. Therefore to ask the question:
Should we think about software design when we program? 
There is a trend in software development which states "developing software products is not about thinking but about doing".  I know many venture people who believe very much in this statement. Yet the reality is that software is a process of thinking (in part at least). Still, from a pure seed-venture-money game, the rule of "it is not about thinking" is true"! Because the number one rule is "be fast" and thinking too much will very much slow you down.

Is it then both true and untrue, that we should both use and not use our brains when we write software? Yes, and yes! And it is exactly this subtle challenge that makes software management in innovation a tricky game.

Thinking can be done different ways, different approaches can be taken. Some are efficient, some are a waste of time. Some will help your software grow, others will block you. Some will help you meet your deadline, others will invariably lead to failure. The game is then only to think in the ways that help you!

Some of my colleagues have heard me condense these concepts into one statement:
It is about thinking backwards!
There are many ways to do this. I will cover just a few here, there are in fact as many more.

Play to win above all else

In recent blitz chess games, FM Lefong Hua repeats "it is not about calculating the end's win game", (because that is not a guarantee win), instead is about about "flagging your opponent". By which he means, winning is not about thinking within the classical rules of chess, it is about meeting the "win conditions", which in blitz chess games is much about not running out of time (being flagged).

Transposed into a software development, that means it is not about meeting the classical rules of software design, it is about thinking through how to always meet your goals and deliver results. Or to be more specific, it is about thinking backward, to find a path back from your "runnable software" goals, to your current status that guarantees your development success.

The heart of your software comes first

I have mentioned that "One of the little understood properties of programming is that at the lowest level things tend to be single dimensional".  A good software design builds a "break" or "separation" in that unique dimension "just about where your main product abstraction is", to achieve a sandwich like design where new product abstractions are added "by reassembly" of the two separated parts.

There are few ways to do this, domain specific languages (DSL) and functional programming (FP) being my favoured approaches.  While all my major software developments had DSLs, it was only much later in my career that I understood that what was working for me was not the DSLs but the effort to maintain separation between interpreter and interpreted abstractions. This separation is naturally achieved with a DSL, yet can also be achieved with adjunctive higher order FP. (The "ultimate tool" is then to combine the two concepts as adjunctive FP based DSLs, which was the base of Elevence's contract language).

Be functional and agile

Agile development is a lot about prioritizing your requirements and implementing them in work iterations. That means that the first level of your design, what might be seen as the first draft of primary keys of your data base, are directly tied to the most important business concept (taken from OO vs FP vs agile). The trick is then not to see this as a database of data, where keys are data, but a database of code, where keys are functional properties such as APIs with specific invariants (e.g. somewhat like class types in Haskell). The extended trick is then also to make this a normalized design (just like a normalized classical DB schema, but in a the "functional space"), for example by using linear types.


Brute force yes, but with the right pieces

Let us put this all together, our first conclusion is when building new software:
Use brute force and minimal brains to assemble data and call external APIs 
Importantly, keep your program structure as flat as possible when you do this. Which pretty much means to shun OO patterns, and to use as many array and container like constructions as you want.

Then, and this is the tricky part:
Incrementally invest effort to separate interpreter and interpreted abstractions in your code.
Always make sure that these abstractions fit within the plan to your deliverables. That means you are able to think backwards from your deliverable goal, and work out the path to your current development state, the path which you will follow to build your code. An agile process and a good team will make this an easier job. Also, all those arrays and containers will need to fit into a single unified concept (e.g. such as indexed tensors).

It's complicated

Sometimes things are just too complicated. Many developers do not know how to "separate interpreter and interpreted abstractions".  Here I will be honest, it is not easy. And just to make this clear, the last DSL I wrote took me multiple tries until "I got it right".  Also, to mention that embedding product abstraction in higher order FP is even harder than writing DSLs.

Worse, the process is "hack brute force" to assemble data and use external APIs, and only then think about how you can slice your interpretive abstractions. These means that initially, software development is about doing, not thinking. Tricky...

Welcome to 2020

I have been writing this blog for almost 15 years. Interestingly, a major change over these years is that there is so much well integrated open source software (OSS) out there that it is cheaper to "just try" than to "think" (when using OSS and third party APIs). And in part it was this reality that led me to write this blog today. Enjoy, and stay safe!

All original content copyright James Litsios, 2020.

Wednesday, September 25, 2019

Agile process vs Data Management

Modern architecture, for example for large cloud systems, have much in common with agile processes. You may know from past posts that I love agile processes. One reason is that agile processes have mathematical roots. The other is that when you know how to yield them, they deliver. I could talk for two hours on the subject! Here, for your comfort, the focus is just on the basic tie between an agile process and the architecture of modern data management.
Here is the video (9m):


Pictures from the video

Hereunder, the main pictures of the video, in case you want to refer to them in your comments:

1) Concrete vs Abstract (horizontally) and Static vs Dynamic (vertically):

(Note how I say concrete, but write "contract" in the video. That is a mistake, and what happens when you invent smart contracts and focus much on them!).

2) Agile process "functional schema" and data management "functional schema" side by side:


3) Waterfall process (red):

4) Agile iterative process (blue):

5) Traditional database architecture (red):

6) Modern data management architecture (blue):


Yes, in case you are wondering: my left hand is holding my iphone as I record. 
As always, comments are welcome, especially from old friends!

Wednesday, May 15, 2013

Agile keeps you from being stupid

Have you noticed that people can make sense of what does not make sense when they do not understand it? That is the "soft" and "analogic" property of our brain: we can make sense out of nonsense,  and this is ok, when we do not know it is nonsense!
A waterfall process will take nonsense, and then often spend the money while delivering nonsense.
Agile process will take nonsense, and fail iterations, and... just go on, spend your money, and  delivery nonsense, or...,  recognise the stalling as a failure to deliver the requirements (e.g. sprint stories), and then force the requirements to be rewritten for the next development iteration. The next iteration may fail, but again the requirements will need to be rewritten. Yet if you are truthfully applying an agile process, each failed delivery will again attempt to reformulate the requirements to be achievable and in the end what was not understood and is blocking you becomes understood and you either stop the project, or you understand how remove the blocker.

Wednesday, July 18, 2012

Managing software development

This blog entry is more than of a little essay than a blog posting, the question I am trying to answer is what are my key learnings in managing software development.
Software development management is about achieving business success, as well as team and individual success, by leveraging skills and process while focusing on productivity and learning. I know this because I have experienced it and applied it as developer, architect, product owner, project management, scrum master, development manager and CTO.
Software development is a self-sustained process: much of what needs to be done depends on what has been done, much of future productivity depends on existing team culture and past investments. It is when starting up greenfield software projects that this “chicken and egg” nature of development is especially noticeable, developers starting in completely new domains are often acutely aware of what they do not know. They may not know, for example, who are their users, what are their requirements, what architecture to use, how they will test their deliverable, or which third party technology to use.  The team itself may not know how to work together, nor how to best invest their efforts to keep productivity high. The sad story is that many development projects fail because they go too far into these “uncharted territories of knowledge. The good story is that applying a good process with enough experienced people will help you stay away from taking unmanageable risk.
Good developers are naturally top of my list of what makes a good development team; Developers bring dexterity of “thinking in code” and also bring broader application and work culture experience with them. You would be surprised how much bad experience a developer can acquire, so beware how you build your team. My experience is that observing a developer working out a solution gives you the best insight of the technical skills they have acquired, as well as their cultural skills; Therefore to hire developers, I prefer case interviews with real coding tasks, while making sure that there is enough people presence and open items to push the candidates to interact and show their soft skills.
Most developers are grown up enough to manage themselves… most of the time. Therefore, although I have run waterfall processes, I really recommend agile development because it gives developers their independence while regularly confronting them with the realities of “the real world”.  A key role to help them in this process of “confronting the facts”, is the requirement manager (e.g. product owner). He/she brings analytical domain expertise but also the product evangelism that aligns the development team around the product features. Getting people to agree is much easier when they already agree about something; Therefore, having your teams agree with your requirement managers makes it much easier for them to agree “together” on how they will design, build and test software.  My experience, as product owner in a high frequency derivatives trading environment, is that the biggest challenge in product management is aligning commercial expectations and development throughput. That brings up the subject of a development’s team productivity and good places to look for it are in architecture, QA  and build management.
Architecture, quality assurance, and build management are magical ingredients to software development: get them right and you rarely need to revisit them, but get them wrong, and they will drag you through hell, especially hell of lost productivity, productivity that often makes the difference between success and failure. One thing these three development processes have in common is that they are not needed to start development. Another is that they are best managed as a “coordinated” solution across development, and not as an assembly of different solutions: you want to have one build management, one architecture, one notion of QA. That does not necessarily mean one “uniform” solution, good solutions often have a granularity of diversity, but there is an optimal balance of overall cohesion versus local choices. And that is what make these particularly tricky to manage, both as a team effort and as part of development management.
There are two key understanding in team management, independently whether it is a top-down style of management or a self-managed team: The first is very tight relation between what can be changed and what should not be changed, the second is the importance of sharing knowledge and beliefs among all team members.  I will not dig deeper in the importance of sharing, there is no notion of team without it, yet first is crucial to understand how to manage cross team activities, especially with regards to productivity.  The reasoning is as follows:
  • To improve productivity it makes sense to change things; It makes sense that you look for a better architecture (e.g. refactor designs), a better build system (e.g. bring in a new tool), a better test coverage (e.g. new tests).
  • Yet making changes makes less sense when near optimum productivity.
The consequence of this is that your number one mission as a development manager is to help your teams track their productivity, stay aligned around their commitments (e.g. encourage discipline and hard work!), and that they maintain a common  and realistic notion of “optimality”. Achieve this, and your development team will know what to change and when to make changes. They will decide if it is worth investing to improve the architecture, the build system or the QA.
Pain point in all of this is achieving that REALISTIC notion of optimality, and getting agreement around a “discount factor” for sustainability, no everything should be 100% sustainable. Give your requirement management the mission to evangelize all with their product oriented view of realism. Getting the right balance in what is sustainable and not really depends on your budget!