Core Concepts
Concepts introduced in LAD may differ from your vision!
The truth is that there is no “correct definition”.
We try to make the concepts we introduce correlate with generally accepted ones. But our main task is to create a unified non-contradictory system.
For those who know DDD, we create ubiquitous language in the bounded context of LAD
Be aware that the concepts introduced by LAD are basically created only for use in LAD.
Abstraction
The most important term of all architecture. Everything we will do is create abstractions, move code between abstractions, build relationships between abstractions.
Sounds complicated but actually abstraction is any way to hide code, complexity any information, behind a name and public interface.
The essence of abstraction is that you can understand what’s inside even without reading the content
// Variable is an abstractionconst userList = [];
// The variable name is enough to guess what's thereuserList.map((user) => user);
// Function is an abstractionfunction createUser(name: string): Promise<User> { // ... Many lines of complex code}
// By calling this function we know it will create a user and return it, even without reading the source codeconst user = await createUser("0xFrizen.eth");
// Class is an abstractionclass Board { addCard(title: string) { // ... Many lines of complex code } removeCard(id: string) { // ... Many lines of complex code } renderHTML(): string { // ... Many lines of complex code }}// When we use this class, we understand that calling methods will add cards to the board.// And calling renderHTML will return html of this board even without reading the source codeconst board = new Board();board.addCard("Card 1");board.removeCard("Card 1");document.body.innerHTML = board.renderHTML();
// File is an abstraction// Just the file name is enough for us to assume what's thereimport {} from "./use-user-list";
// Folder is an abstraction// Thanks to the folder name we know,// that UserCard is a componentimport { UserCard } from "./components/user-card";Important: not all abstractions are expressed in code
Concepts, terms, patterns - these are all abstractions
// By the name we understand that this is a component// This means:// - You can use hooks there// - You need to return jsx from there// - There should be no side effects in the bodyfunction UserComponent() {}With the help of abstractions we can get a lot of information from a small amount of code
You can read more about this here Abstraction
Miller’s Wallet
Okay, we figured out what abstraction is, but why do we need it?
The thing is that the human brain thinks in abstractions. Not symbols, not words, not lines of code, but abstractions.
More about this here Neurophysiology of code complexity
And this thinking has an important limitation, which is the basis of code complexity.
At the same time we can only think about 7+-2 abstractions. (Usually around 4x)
This rule is called Miller’s wallet
Try to understand 2 pieces of code:
const maxSubArray = (nums) => { let maxSub = nums[0]; let curSum = 0; for (let i = 0; i < nums.length; i++) { if (curSum < 0) { curSum = 0; } curSum += nums[i]; maxSub = Math.max(maxSub, curSum); } return maxSub;};const user = { id: 1, name: "Alex Johnson", email: "alex@example.com", avatar: "https://i.pravatar.cc/150?img=3", role: "Software Engineer", bio: "Full-stack developer specializing in React & Node", location: "San Francisco, CA", joined: "2022-03-15", followers: 1243, following: 562,};Why is the first one significantly more difficult to understand than the second one, although both have 11 lines of code?
In the first case, we work with a large number of abstractions simultaneously: loop, Math.max, conditions maxSub, curSum There’s little code but the wallet is overflowing.
And in the second case, there are few simultaneous abstractions - user, object declaration