𝔖 Scriptorium
✦   LIBER   ✦

📁

Clean Code Principles and Patterns, 2nd Edition : A Software Practitioner's Handbook

✍ Scribed by Petri Silen


Publisher
Leanpub
Year
2024
Tongue
English
Leaves
672
Edition
2
Category
Library

⬇  Acquire This Volume

No coin nor oath required. For personal study only.

✦ Synopsis


One of the most comprehensive no-fluff guides for software developers to help them write clean code every day. The book is packed with principles and patterns that help developers, from novices and juniors to seniors and experts, to write cleaner code.

Clean Code Principles and Patterns is one of the most comprehensive no-fluff guides for software developers to help them write clean code every day. The author Petri Silén has almost 30 years of industry experience in designing and implementing software, and now he puts all his knowledge gained during the years into this book. The book is packed with principles and patterns that help developers, from novices and juniors to seniors and experts, to write cleaner code. The principles and patterns presented in the book are accompanied by realistic yet straightforward examples to help the reader to understand them better. Examples are written in Java, JavaScript/TypeScript, and C++. Most of the examples are directly applicable to other programming languages, too. Also, having basic knowledge of Docker and Kubernetes concepts is beneficial. The reader should have basic knowledge of one object-oriented programming language to get the full benefit from this book. All the major examples presented in the book are available in a public GitHub repository.

The book is divided into ten chapters

Architectural design principles
Object-oriented design principles
Coding principles
Testing principles
Security principles
API design principles
Database types and related principles
Concurrent programming principles
Agile and teamwork principles
DevSecOps

After reading this book, you will know the following and much more

How to architect modern cloud-native microservices (examples with Kubernetes)
What are autopilot microservices
What are event sourcing, CQRS, distributed transactions, saga orchestration pattern, and saga choreography pattern
What are the five SOLID principles, and how to put them into use in real-life code
What are the 25 design patterns, and how to use them
Law of Demeter, Tell, don't ask principle, YAGNI, primitive obsession
What is the MVC pattern, and how MVP and MVVM differ from each other
What is clean (or hexagonal) architecture and vertical slice architecture
Why and how to use dependency injection
Detailed instructions with concrete examples on how to uniformly name various software entities like classes, functions, and variables
Why you should prefer composition over inheritance
Strategic and tactical domain-driven design (DDD) with examples
How to organize a source code repository
How to organize code into directories
Concrete ways how to avoid writing comments and refactor comments away
What are the most common issues that static code analyzers find, and how to correct them
Most important refactoring techniques for everyday use
Why you should use a statically typed language
How to correctly handle errors and exceptions
How to not forget handle errors and exceptions
Why you should never pass or return a null value
How to avoid off-by-one errors effectively
What you should remember when using a Google search to get answers
When and how to optimize code
TDD, Detroit/Chicago vs. London schools, Unit testing, mocking, integration testing, E2E testing, and non-functional testing
What is threat modeling and how to conduct it
Authentication and authorization using OpenID Connect and OAuth2
What are the essential security features to implement in an application
How to design APIs using technologies like JSON-RPC, REST, GraphQL, SSE, WebSocket, gRPC, and event-driven services
When and how to use a relational database, document database, key-value store, or wide-column database
How to avoid SQL injection attacks using ORM or parameterized SQL queries
When to use threading or parallel algorithms and how to ensure thread safety
What principles to follow when working in a software development team
What are DevOps, SecOps, and continuous integration (CI), and what is the difference between continuous delivery (CD) and continuous deployment (CD). Examples with Docker, Kubernetes and GitHub Actions.

✦ Table of Contents


Clean Code Principles and Patterns, 2nd Edition
1: About the Author
2: Introduction
3: Architectural Principles and Patterns
3.1: Software Hierarchy
3.2: The Twelve-Factor App
3.3: Single Responsibility Principle
3.4: Uniform Naming Principle
3.5: Encapsulation Principle
3.6: Service Aggregation Principle
3.7: High Cohesion, Low Coupling Principle
3.8: Library Composition Principle
3.9: Avoid Duplication Principle
3.10: Externalized Service Configuration Principle
3.10.1: Environment Variables
3.10.2: Kubernetes ConfigMaps
3.10.3: Kubernetes Secrets
3.10.4: External Store
3.11: Service Substitution Principle
3.12: Inter-Service Communication Methods
3.12.1: Synchronous Communication Method
3.12.2: Asynchronous Communication Method
3.12.3: Shared Data Communication Method
3.13: Strategical Domain-Driven Design Principle
3.13.1: Strategical DDD Example 1: Mobile Telecom Network Analytics Software System
3.13.2: Strategical DDD Example 2: Banking Software System
3.14: Autopilot Microservices Principle
3.14.1: Stateless Microservices Principle
3.14.2: Resilient Microservices Principle
3.14.3: Horizontally Autoscaling Microservices Principle
3.14.4: Highly-Available Microservices Principle
3.14.5: Observable Microservices Principle
3.15: Individually Deployable Microservices Principle
3.16: Software Versioning Principles
3.16.1: Use Semantic Versioning Principle
3.16.2: Avoid Using 0.x Versions Principle
3.16.3: Don’t Increase Major Version Principle
3.16.4: Implement Security Patches and Bug Corrections to All Major Versions Principle
3.16.5: Avoid Using Non-LTS Versions in Production Principle
3.17: Git Version Control Principle
3.17.1: Feature Branch
3.17.2: Feature Toggle
3.18: Architectural Patterns
3.18.1: Multi-Container Design Patterns
3.18.1.1: Sidecar Pattern
3.18.1.2: Ambassador Pattern
3.18.1.3: Adapter Pattern
3.18.2: Circuit Breaker Pattern
3.18.3: Competing Consumers Pattern
3.18.4: API Gateway Offloading Pattern
3.18.5: Retry Pattern
3.18.6: Static Content Hosting Pattern
3.18.7: Event Sourcing Pattern
3.18.8: Command Query Responsibility Segregation (CQRS) Pattern
3.18.9: Distributed Transaction Patterns
3.18.9.1: Saga Orchestration Pattern
3.18.9.2: Saga Choreography Pattern
3.19: Preferred Technology Stacks Principle
3.20: 8 Fallacies Of Distributed Computing
4: Object-Oriented Design Principles
4.1: Object-Oriented Programming Concepts
4.1.1: Classes/Objects
4.1.2: Encapsulation
4.1.3: Abstraction
4.1.4: Inheritance
4.1.5: Interface
4.1.5.1: Interface evolution
4.1.6: Polymorphism
4.2: Programming Paradigms
4.2.1: Imperative Programming
4.2.2: Functional Programming
4.3: Multi-Paradigm Programming Principle
4.4: Why is Object-Oriented Programming Hard?
4.5: SOLID Principles
4.5.1: Single Responsibility Principle
4.5.2: Open-Closed Principle
4.5.3: Liskov’s Substitution Principle
4.5.4: Interface Segregation and Multiple Inheritance Principle
4.5.5: Program Against Interfaces Principle (a.k.a. Generalized Dependency Inversion Principle)
4.6: Clean Architecture Principle
4.6.1: Real-Life Example
4.7: Vertical Slice Architecture Principle
4.8: Class Organization Principle
4.9: Package/Directory, Class and Function Sizing Principle
4.10: Uniform Naming Principle
4.10.1: Naming Interfaces and Classes
4.10.2: Naming Functions
4.10.2.1: Preposition in Function Name
4.10.2.2: Example 1: Renaming JavaScript Array Methods
4.10.2.3: Naming Method Pairs
4.10.2.4: Naming Boolean Functions (Predicates)
4.10.2.5: Naming Builder Methods
4.10.2.6: Naming Methods with Implicit Verbs
4.10.2.7: Naming Property Getter Functions
4.10.2.8: Naming Lifecycle Methods
4.10.2.9: Naming Generic Type Parameters
4.10.2.10: Naming Function Parameters
4.11: Encapsulation Principle
4.11.1: Immutable Objects
4.11.2: Don’t Leak Modifiable Internal State Outside an Object Principle
4.11.3: Don’t Assign From a Method Parameter to a Modifiable Attribute
4.12: Prefer Composition Over Inheritance Principle
4.13: Tactical Domain-Driven Design Principle
4.13.1: Tactical DDD Concepts
4.13.1.1: Entities
4.13.1.2: Value Objects
4.13.1.3: Aggregates
4.13.1.4: Aggregate Roots
4.13.1.5: Actors
4.13.1.6: Factories
4.13.1.7: Repositories
4.13.1.8: Services
4.13.1.9: Events
4.13.1.10: Design-Level Event Storming
4.13.2: Tactical DDD Example 1: Data Exporter Microservice
4.13.3: Tactical DDD Example 2: Anomaly Detection Microservice
4.14: Design Patterns
4.14.1: Design Patterns for Creating Objects
4.14.1.1: Factory Pattern
4.14.1.2: Abstract Factory Pattern
4.14.1.3: Static Factory Method Pattern
4.14.1.4: Builder Pattern
4.14.1.5: Singleton Pattern
4.14.1.6: Prototype Pattern
4.14.1.7: Object Pool Pattern
4.14.2: Structural Design Patterns
4.14.2.1: Composite Pattern
4.14.2.2: Facade Pattern
4.14.2.3: Bridge Pattern
4.14.2.4: Strategy Pattern
4.14.2.5: Adapter Pattern
4.14.2.6: Proxy Pattern
4.14.2.7: Decorator Pattern
4.14.2.8: Flyweight Pattern
4.14.3: Behavioral Design Patterns
4.14.3.1: Chain of Responsibility Pattern
4.14.3.2: Observer Pattern
4.14.3.3: Command/Action Pattern
4.14.3.4: Iterator Pattern
4.14.3.5: Interpreter Pattern
4.14.3.6: State Pattern
4.14.3.7: Mediator Pattern
4.14.3.8: Template Method Pattern
4.14.3.9: Memento Pattern
4.14.3.10: Visitor Pattern
4.14.3.11: Null Object Pattern
4.15: Don’t Ask, Tell Principle
4.16: Law of Demeter
4.17: Avoid Primitive Obsession Principle
4.18: You Aren’t Gonna Need It (YAGNI) Principle
4.19: Dependency Injection (DI) Principle
4.20: Avoid Code Duplication Principle
4.21: Inheritance in Cascading Style Sheets (CSS)
5: Coding Principles
5.1: Uniform Variable Naming Principle
5.1.1: Naming Integer Variables
5.1.2: Naming Floating-Point Number Variables
5.1.3: Naming Boolean Variables
5.1.4: Naming String Variables
5.1.5: Naming Enum Variables
5.1.6: Naming Collection (List and Set) Variables
5.1.7: Naming Map Variables
5.1.8: Naming Pair and Tuple Variables
5.1.9: Naming Object Variables
5.1.10: Naming Optional Variables
5.1.11: Naming Function Variables (Callbacks)
5.1.12: Naming Class Properties
5.1.13: General Naming Rules
5.1.13.1: Use Short, Common Names
5.1.13.2: Pick One Term And Use It Consistently
5.1.13.3: Avoid Obscure Abbreviations
5.1.13.4: Avoid Too Short Or Meaningless Names
5.2: Uniform Source Code Repository Structure Principle
5.2.1: Java Source Code Repository Structure
5.2.2: C++ Source Code Repository Structure
5.2.3: JavaScript/TypeScript Source Code Repository Structure
5.3: Domain-Based Source Code Structure Principle
5.4: Avoid Comments Principle
5.4.1: Name Things Properly
5.4.2: Single Return Of Named Value At The End Of Function
5.4.3: Return Type Aliasing
5.4.4: Extract Constant for Boolean Expression
5.4.5: Extract Named Constant or Enumerated Type
5.4.6: Extract Function
5.4.7: Avoid Comments for Regular Expression
5.4.8: Name Anonymous Function
5.4.9: Avoiding Comments in Bash Shell Scripts
5.5: Function Single Return Principle
5.6: Prefer a Statically Typed Language for Production Code Principle
5.6.1: Function Arguments Might Be Given in Wrong Order
5.6.2: Function Argument Might Be Given with Wrong Type
5.6.3: Function Return Value Type Might Be Misunderstood
5.6.4: Refactoring Code Is More Difficult
5.6.5: Forced to Write Public API Comments
5.6.6: Type Errors Are Not Found in Testing
5.7: Refactoring Principle
5.7.1: Rename
5.7.2: Extract Method
5.7.3: Extract Class
5.7.4: Extract Constant
5.7.5: Replace Conditionals with Polymorphism
5.7.6: Introduce Parameter Object
5.7.7: Invert If-Statement
5.7.8: Creating Rich Object
5.8: Static Code Analysis Principle
5.8.1: Common Static Code Analysis Issues
5.9: Error/Exception Handling Principle
5.9.1: Handling Checked Exceptions in Java
5.9.2: Returning Errors
5.9.2.1: Returning Failure Indicator
5.9.2.2: Returning an Optional Value
5.9.2.3: Returning an Error Object
5.9.2.4: Adapt to Wanted Error Handling Mechanism
5.9.2.5: Asynchronous Function Error Handling
5.9.2.6: Functional Exception Handling
5.9.2.7: Stream Error Handling
5.10: Don’t Pass or Return Null Principle
5.11: Avoid Off-By-One Errors Principle
5.12: Be Critical When Googling or Using Generative AI Principle
5.13: Make One Change At A Time Principle
5.14: Choosing Right 3rd Party Component Principle
5.15: Use Appropriate Data Structure Principle
5.15.1: Map
5.15.2: Tuple
5.15.3: Set
5.15.4: String
5.15.5: Deque (Double Ended Queue)
5.15.6: Stack (LIFO Queue)
5.15.7: Queue (FIFO Queue)
5.15.8: Priority Queue
5.16: Optimization Principle
5.16.1: Optimization Patterns
5.16.1.1: Optimize Busy Loops Only Pattern
5.16.1.2: Remove Unnecessary Functionality Pattern
5.16.1.3: Object Pool Pattern
5.16.1.4: Algorithm Complexity Reduction Pattern
5.16.1.5: Cache Function Results Pattern
5.16.1.6: Buffer File I/O Pattern
5.16.1.7: Share Identical Objects a.k.a Flyweight Pattern
5.16.1.8: Copy Memory in Chunks Pattern (C++)
5.16.1.9: Replace Virtual Methods with Non-Virtual Methods Pattern (C++)
5.16.1.10: Inline Methods Pattern (C++)
5.16.1.11: Use Unique Pointer Pattern (C++)
6: Testing Principles
6.1: Functional Testing Principles
6.1.1: Unit Testing Principle
6.1.1.1: TDD Schools: London vs. Detroit/Chicago
6.1.1.2: Test-Driven Development (TDD)
6.1.1.3: Unit Specification-Driven Development (USDD)
6.1.1.4: Naming Conventions
6.1.1.5: Mocking
6.1.1.6: Web UI Component Testing
6.1.2: Software Component Integration Testing Principle
6.1.2.1: Web UI Integration Testing
6.1.2.2: Setting Up Integration Testing Environment
6.1.3: Complete Example with BDD, ATDD, DDD, OOD and TDD
6.1.4: End-to-End (E2E) Testing Principle
6.2: Non-Functional Testing Principle
6.2.1: Performance Testing
6.2.2: Data Volume Testing
6.2.3: Stability Testing
6.2.4: Reliability Testing
6.2.5: Stress and Scalability Testing
6.2.6: Security Testing
6.2.7: Other Non-Functional Testing
6.2.7.1: Visual Testing
7: Security Principles
7.1: Shift Security to Left Principle
7.2: Have a Product Security Lead Principle
7.3: Use Threat Modelling Process Principle
7.3.1: Decompose Application
7.3.2: Determine and Rank Threats
7.3.2.1: STRIDE method
7.3.2.2: STRIDE Threat Examples
7.3.2.3: Application Security Frame (ASF) method
7.3.3: Determine Countermeasures and Mitigation
7.3.4: Threat Modeling Example using STRIDE
7.3.4.1: Decompose Application
7.3.4.2: Determine and Rank Threats
7.3.5: Determine Countermeasures and Mitigation
7.3.6: Threat Modeling Example Using ASF
7.4: Security Features
7.4.1: Authentication and Authorization
7.4.1.1: OpenID Connect Authentication and Authorization in Frontend
7.4.1.2: OAuth2 Authorization in Backend
7.4.2: Password Policy
7.4.3: Cryptography
7.4.3.1: Encryption Key Lifetime and Rotation
7.4.4: Denial-of-service (DoS) Prevention
7.4.5: Database Security
7.4.6: SQL Injection Prevention
7.4.7: OS Command Injection Prevention
7.4.8: Security Configuration
7.4.9: Automatic Vulnerability Scanning
7.4.10: Integrity
7.4.11: Error Handling
7.4.12: Logging
7.4.13: Audit Logging
7.4.14: Input Validation
7.4.14.1: Validating Numbers
7.4.14.2: Validating Strings
7.4.14.3: Validating Timestamps
7.4.14.4: Validating Arrays
7.4.14.5: Validating Objects
7.4.14.6: Validating Files Uploaded to Server
7.4.14.7: Validation Library Example
8: API Design Principles
8.1: Frontend Facing API Design Principles
8.1.1: JSON-based RPC API Design Principle
8.1.2: REST API Design Principle
8.1.2.1: Creating a Resource
8.1.2.2: Reading Resources
8.1.2.3: Updating Resources
8.1.2.4: Deleting Resources
8.1.2.5: Executing Non-CRUD Actions on Resources
8.1.2.6: Resource Composition
8.1.2.7: HTTP Status Codes
8.1.2.8: HATEOAS and HAL
8.1.2.9: API Versioning
8.1.2.10: Documentation
8.1.2.11: Implementation Example
8.1.3: GraphQL API Design
8.1.4: Subscription-Based API Design
8.1.4.1: Server-Sent Events (SSE)
8.1.4.2: GraphQL Subscriptions
8.1.5: WebSocket Example
8.2: Inter-Microservice API Design Principles
8.2.1: Synchronous API Design Principle
8.2.1.1: gRPC-Based API Design Example
8.2.2: Asynchronous API Design Principle
8.2.2.1: Request-Only Asynchronous API Design
8.2.2.2: Request-Response Asynchronous API Design
8.2.2.3: Asynchronous API Documentation
8.3: API Design Example
9: Databases And Database Principles
9.1: Relational Databases
9.1.1: Structure of Relational Database
9.1.2: Use Object Relational Mapper (ORM) Principle
9.1.2.1: Entity/Table Relationships
9.1.2.1.1: One-To-One/Many Relationships
9.1.2.1.2: Many-To-Many Relationships
9.1.2.2: Sales Item Repository Example
9.1.3: Use Parameterized SQL Statements Principle
9.1.3.1: Sales Item Repository Example
9.1.4: Normalization Rules
9.1.4.1: First Normal Form (1NF)
9.1.4.2: Second Normal Form (2NF)
9.1.4.3: Third Normal Form (3NF)
9.2: Document Databases
9.2.1: Sales Item Repository Example
9.3: Key-Value Database Principle
9.4: Wide-Column Databases
9.5: Search Engines
10: Concurrent Programming Principles
10.1: Threading Principle
10.1.1: Parallel Algorithms
10.2: Thread Safety Principle
10.2.1: Synchronization Directive
10.2.2: Atomic Variables
10.2.3: Concurrent Collections
10.2.4: Mutexes
10.2.5: Spinlocks
11: Agile and Teamwork Principles
11.1: Twelve Principles of Agile Software
11.2: Use Agile Framework Principle
11.3: Define the Done Principle
11.4: You Write Code for Other People Principle
11.5: Avoid Technical Debt Principle
11.6: Software Component Documentation Principle
11.7: Code Review Principle
11.7.1: Focus on Object-Oriented Design
11.7.2: Focus on Removal of Duplicate Information (DRY principle)
11.7.3: Focus on Spreading Knowledge
11.7.4: Focus on Function Specification by Unit Tests
11.7.5: Focus on Proper and Uniform Naming
11.7.6: Don’t Focus on Premature Optimization
11.7.7: Detect Possible Malicious Code
11.8: Uniform Code Formatting Principle
11.9: Highly Concurrent Development Principle
11.9.1: Dedicated Microservices and Microlibraries
11.9.2: Dedicated Domains
11.9.3: Follow Open-Closed Principle
11.10: Pair Programming Principle
11.11: Mob Programming Principle
11.12: Ask and Offer Help Principle
11.13: Well-Defined Development Team Roles Principle
11.13.1: Product Owner
11.13.2: Scrum Master
11.13.3: Software Developer
11.13.4: Test Automation Developer
11.13.5: DevOps Engineer
11.13.6: UI Designer
11.14: Competence Transfer Principle
11.15: Inter-Team Communication Principle
12: DevSecOps
12.1: SecOps Lifecycle
12.2: DevOps Lifecycle
12.2.1: Plan
12.2.2: Code
12.2.3: Build and Test
12.2.4: Release
12.2.4.1: Example Dockerfile
12.2.4.2: Example Kubernetes Deployment
12.2.4.3: Example CI/CD Pipeline
12.2.5: Deploy
12.2.6: Operate
12.2.7: Monitor
12.2.7.1: Logging to Standard Input
12.2.7.2: Distributed Tracing
12.2.7.3: Metrics Collection
12.2.7.4: Metrics Visualization
12.2.7.5: Alerting
12.2.8: Software System Alerts Dashboard Example
12.2.9: Microservice Grafana Dashboard Example
12.2.9.1: Logging
12.2.9.2: OpenTelemetry Log Data Model
12.2.9.3: PrometheusRule Example
13: Conclusion
14: Appendix A


📜 SIMILAR VOLUMES


Clean Code Principles and Patterns, 2nd
✍ Реtri Silеn 📂 Library 📅 2024 🏛 Leanpub 🌐 English

This book teaches you how to write clean code. It presents software design and development principles and patterns in a very practical manner. This book is suitable for both junior and senior developers. Some basic knowledge of programming in Python is required. All examples in this book are present

Clean Code Principles And Patterns : A S
✍ Petri Silen 📂 Library 📅 2023 🏛 Leanpub 🌐 English

One of the most comprehensive no-fluff guides for software developers to help them write clean code every day. The book is packed with principles and patterns that help developers, from novices and juniors to seniors and experts, to write cleaner code. Clean Code Principles and Patterns is one of

Clean Code Principles And Patterns Pytho
✍ Petri Silen 📂 Library 📅 2024 🏛 Leanpub 🌐 English

One of the most comprehensive no-fluff guides for Python software developers to help them write clean code every day. The book is packed with principles and patterns that help developers, from novices and juniors to seniors and experts, to write cleaner code. Clean Code Principles and Patterns: P

Lean Sigma--A Practitioner’s Guide (2nd
✍ Ian Wedgwood PhD 📂 Library 📅 2016 🏛 Prentice Hall 🌐 English

<P style="MARGIN: 0px"> <B>The Practical Guide to Lean Sigma Problem-Solving— Expanded & Updated!</B> </P> <P style="MARGIN: 0px"> </P> <P style="LINE-HEIGHT: normal; MARGIN: 0px; LAYOUT-GRID-MODE: char; TEXT-AUTOSPACE: ; mso-add-space: auto; mso-layout-grid-align: none" soNormalCxSpMiddle>Lean Sigm

Software Development, Design and Coding:
✍ John F. Dooley 📂 Library 📅 2017 🏛 Apress 🌐 English

<div><p>Learn the principles of good software design, and how to turn those principles into great code. This book introduces you to software engineering ― from the application of engineering principles to the development of software. You'll see how to run a software development project, examine the