Check out a free preview of the full Rapid Application Development with Code Generation course
The "Code Generation Overview" Lesson is part of the full, Rapid Application Development with Code Generation course featured in this preview video. Here's what you'd learn in this lesson:
Lukas discusses managing code complexity, vertical development, horizontal development, and emerging patterns. When clear functional cohesion is achieved from cleanly abstracted layers, natural patterns of convention will emerge.
Transcript from the "Code Generation Overview" Lesson
[00:00:00]
>> Let's talk about architecture. I've used this quote before, I will keep using this quote, because I think it's so absolutely important. So this is from a paper called Out of the Tarpit Ben Moseley Peter Marks. If you Google it, you can find it, it's free and I recommend reading I don't know about half way through the paper it got a little academic.
[00:00:25]
But right in the first page, they make this point, and, it has stuck with ever since. The biggest problem in the development and maintenance of large scale software systems is complexity. Large systems are hard to understand. Everybody collectively just be like, duh but what do we mean by complexity?
[00:00:47]
We believe that the major contributor to this complexity in many systems is the handling of state and the burden that this adds when trying to analyze and reason about the system. Other closely related contributors are code volume, and explicit concern with the flow of control through the system.
[00:01:10]
So, for me, I believe that Redux and by extension NgRx is probably one of the most important inventions or compositions in the modern frontend web stack. And when we look at complexity, more on this, that there are a number of layers that exist within an entire application stack.
[00:01:42]
You have your cloud infrastructure. You have Nx, NgRx, Component Driven Architecture, Observables. And what's interesting about this is that, so one you could replace NgRx with Redux and depending on how you do react, this still absolutely applies. That every one of these layers are concerned with managing complexity.
[00:02:13]
At a micro level, so observables are phenomenal, because at an interaction level or an event level it allows you to manage state, flow control, and code volume. And as you start to iterate over this that component driven architecture allows you to manage complexity at the presentation layer. That NgRx or Redux allows you to manage complexity at the state layer or the application layer.
[00:02:45]
Nx when I say Nx, I mean Nx Dev tools by Narwhal that this allows you to manage complexity at the file structure level, and then infrastructure level that you can use things like infrastructures code. I'm a pretty big fan of the serverless framework, lambda and these different things Docker.
[00:03:07]
But ultimately what you're doing is you're managing complexity at a macro level. And so when we realize that we're managing complexity kind of in this vertical orientation on the stack, that we can start to think about like what are the patterns that exist going this way? And at the same time, historically, when we build applications and so this is a really, really important shift that we need to make.
[00:03:39]
We think of application development in a vertical sense of like we've got this feature and we need to build this thing. So we might need to build the component layer and then we need to build like the state layer then we need to build let's say your HTTP layer to your server communication layer.
[00:04:02]
And then you move on the next feature and you move on the next feature and you move on to the next feature. And so this is when we think of application development. And we are vertically oriented just by default this is just how this works so if you think about how our teams organized typically within an organization well.
[00:04:30]
It's usually around product teams or feature teams and the problem is that and remember I said we are managing complexity at these various levels. That across these features we are managing that complexity the same exact way. But when you are in a vertical slice if you solve a problem in one slice and somebody else solves it in another slice, how do you know about that?
[00:05:12]
And so what you have is, you have these decoupled architecture in not a good way I would say it's essentially cohesion, that like anti cohesion versus. And so now we think of just by default vertical development I building this feature and I'm working on this layer right here and then I'm gonna move to this one I'm gonna move to this one.
[00:05:38]
And we fail to realise that as we build our features that there is a lot of commonality, a lot of patterns to be recognized across all of the components. There is a lot of convention that exist across the logic layer around all of these features and the data layer exactly the same.
[00:06:12]
And so what we start to notice is that when you start to shift your thinking from a vertical orientation, I'm thinking about this implementation in the context of this feature. And you start to think about your applications horizontally in other words not about the feature but about the particular layer.
[00:06:41]
So I don't want to think about the service for courses so I have a service course I want to think about all of the services that this allows you to start to notice patterns of convention. This also allows you to notice patterns of duplication to where like I'm doing this thing over here.
[00:07:06]
But over here in this other feature, I'm doing this thing over here. And as a result, we realized that for convention that this is a candidate, we can optimize this through automation and through automation, that tactically we can build tools for generation. In terms of duplication, that duplication is optimized via elimination.
[00:07:35]
How do we do that? Well consolidation and so if you remember back to my quote complexity managing of state. So now with Redux the reason why I love this is you have all of your code or all of your state in a single state tree you are eliminating all these floating stateful bits.
[00:08:01]
And you're consolidating them into a single state tree. And its the same time, is that with reactive frameworks like angular and react, that you're now because everything is consolidated, it's a lot easier to control how that information flows through your application. So unidirectional data flow, you even get a separation between commands and queries.
[00:08:26]
So when they say state flows down events flow up, well queries state flows down, that's all in one direction. You have an established one way street, unidirectional for those four state to flow down, and then you can issue commands back up. And so you start to recognize the patterns between convention and duplication.
[00:08:52]
More importantly, it's really important to understand that convention is not duplication. And so it's very common with like Redux and NgRx to say like, well, there's just all this boilerplate and boilerplate implies code that doesn't need to exist extraneous code, ie duplicated code. And just because something looks similar to something else doesn't mean that they're doing the same exact thing.
[00:09:31]
In fact, if they're operating on different domain models, they're definitely not doing the same thing. In other words, you couldn't just replace one with the other and vice versa. And so it's really important to understand that duplication is not convention convention is not duplication. And convention is good because it presents an opportunity for automation via generation duplication, believe it or not, when you recognize it presents an opportunity for elimination by consolidation.
[00:10:06]
So, when we achieve clear functional cohesion from cleanly abstracted layers, natural patterns of convention will emerge. So this is really, really important and I don't want to rush to this statement because it's a little dense. But when we're able to take our code and create functional cohesion, other words that things that do similar things are or perform a function is that they're being grouped together.
[00:10:41]
So, cohesion is basically just logical grouping. It's like the opposite of coupling that when we can create functional cohesion into cleanly, abstracted layers. That all of a sudden you start to realize that there is a lot of convention that exists within this application. And so, this is too big for a tweet but, fine-grained functionality reduces code variance between domain models.
[00:11:16]
This is why if you go read any classic architecture book and, not even classic like, pretty much most architects, and people that are creating content in the space. That they're constantly talking about fine grained single purpose code. So, fine grained functionality, reduces covariances between domain models. And when you have fine grained functionality what you realize is that performing an action on one model is almost identical to the same action on any other model.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops