# Topic covered
* First Principles
* The stack
  * Clean Code
  * Programing Paradigms
  * Object Oriented Programming
  * Design Principles
  * Design Patterns
  * Architectural Principles
  * Architectural Styles
  * Architecture Patterns
  * Enterprise Patterns

You ever think about what it took for some of the world’s most skilled developers to learn how to build systems within companies like Uber, YouTube, Facebook, or GitHub?

Even though you know how to write code to make things work at least once, the bigger challenge is to figure out how to write code that makes it easy to change in order to keep up with the current requirements.

If software cannot be changed easily, that makes it bad software, because it prevents us from satisfying the current needs of our users.

Anytime I face a complex problem, I go back to first principles.

1. First Principles

First principles is the most effective way to break down problems.

It works by deconstructing a problem all the way down to the atomic level where we can’t deconstruct it anymore, and then reconstructing a solution from the parts that we’re absolutely sure are true.

Since it’s important to make sure that software was designed in order to be changed we need to follow Software design and architecture principles.

1.1 The stack

The software design and architecture stack shows all of the layers of software design, from the most high-level concepts to the most low-level details.

The stack, includes examples to some of the most important concepts at that layer, but not all (because there are way too many).

Stack

Clean Code
Programing Paradigms
Object Oriented Programming
Design Principles
Design Patterns
Architectural Principles
Architectural Styles
Architecture Patterns
Enterprise Patterns

Stage 1: Clean code

Read More: /tags/clean-code/

The very first step towards creating long-lasting software is figuring out how to write clean code.

  • Clean code can be understood easily – by everyone on the team.
  • Clean code can be read and enhanced by a developer other than its original author.

With understandability comes readability, changeability, extensibility and maintainability.

# Learning resources -- Books
1. Clean Code, by Robert C. Martin
2. Refactoring, by Martin Fowler (2nd edition)
3. The Pragmatic Programmer, by Andy Hunt and Dave Thomas
4. The Design of Everyday Things, by Don Norman

Stage 2: Programming Paradigms

It would be a good idea to really understand the 3 major programming paradigms and the way they influence how we write code.

  • Object-Oriented Programming is the tool best suited for defining how we cross architectural boundaries with polymorphism and plugins
  • Functional programming is the tool we use to push data to the boundaries of our applications
  • Structured programming is the tool we use to write algorithms

This implies that effective software uses a hybrid all 3 programming paradigms styles at different times.

While you could take a strictly functional or strictly object-oriented approach to writing code, understanding where each excels will improve the quality of your designs.

Stage 3: Object-Oriented Programming

Object-Oriented programming enable us to create a plugin architecture and build flexibility into our projects

OOP comes with the 4 principles of OOP (encapsulation, inheritance, polymorphism, and abstraction) that help us create rich domain models.

Stage 4: Design Principles

Read More: /tags/design-principles/

  • OOP can introduce some design challenges
    • When should I use composition?
    • When should I use inheritance?
    • When should I use an abstract class?

Design principles are really well-established and battle-tested object-oriented best practices that you use as rail-guards.

  • Some examples of common design principles you should familiarize yourself with are:
    • The hollywood principle: “Don’t call us, we’ll call you”
    • The SOLID principles, especially the Single responsibility principle
    • DRY (Do Not Repeat Yourself)
    • YAGNI (You Aren’t Gonna Need It)

Stage 5: Design Patterns

Read More: /tags/design-patterns/

Design pattern is a walkthrough of a well-tested approach that can be used to solve a generally occurring and recurring problem in object-oriented software design.

There are 3 categories of design patterns: creational, structural, and behaviour.

Stage 6: Architectural Principles

Learn how to manage relationship between components, express high level policy and identify architectural boundaries

  • Policy vs details
  • Coupling & Cohesion
  • Component principle
  • Boundaries

Stage 7: Architectural Styles

Learn the different approaches to organizing our code into high-level modules and defining the relationship between them.

  • Structural
    • Monolithic
    • Layered
  • Messaging
    • Event-Driven
    • Publish-subscribe
  • Distributed
    • Client-Server
    • Peer-to-pee

Stage 8: Architectural Patterns

Learn the architectural pattern that implement one or more architectural style to solve a problem

  • Domain-Driven Design
  • Microservices
  • Serverless architecture
  • Model-View Controller

Stage 9: Enterprise patterns

Learn the enterprise patterns that suit your chosen architectural pattern

  • DTOs
  • ORMs
  • Domain Models

LLD Video reference

Steps and Resources to learn LLD as a beginner

What to study for Low Level System Design Interviews

Reference