Chapters 15 16:What Is Architecture?Independence_《clean architecture》notes

server/2025/4/2 6:33:40/

What Is Architecture?&Independence

      • **Chapter 15: What Is Architecture?**
        • **Key Concepts**:
        • **Code Example: Layered Architecture**:
      • **Chapter 16: Independence**
        • **Key Concepts**:
        • **Code Example: Dependency Inversion & Interfaces**:
      • **Combined Example: Boundaries & Independence**
      • **Key Takeaways**:
      • **Chapters 15 & 16 Overview**
      • **10 Hard Difficulty Multiple-Choice Questions**
      • **Test Code Examples**


Chapter 15: What Is Architecture?

Key Concepts:
  1. Definition: Architecture is the shape of a system defined by components, dependencies, and boundaries that manage complexity and enable evolution.
  2. Core Goals:
    • Manage Complexity: Decouple components to isolate changes.
    • Keep Options Open: Delay decisions (e.g., frameworks, databases) to avoid premature constraints.
    • Support Use Cases: Ensure the system delivers business value.
  3. Layers & Boundaries:
    • Separate high-level policy (business logic) from low-level details (I/O, UI).
    • Use boundaries (interfaces, abstractions) to isolate volatile components.
Code Example: Layered Architecture:
#include <iostream>
#include <string>
#include <vector>// High-level Policy (Business Logic)
class Order {
public:virtual double calculateTotal() const = 0;virtual ~Order() = default;
};// Low-level Detail (Implementation)
class ConcreteOrder : public Order {
private:std::vector<double> items;
public:void addItem(double price) { items.push_back(price); }double calculateTotal() const override {double total = 0;for (auto price : items) total += price;return total;}
};// Client Code (Depends on Abstraction)
void printTotal(const Order& order) {std::cout << "Total: $" << order.calculateTotal() << std::endl;
}int main() {ConcreteOrder order;order.addItem(10.5);order.addItem(20.3);printTotal(order); // Output: Total: $30.8return 0;
}

Explanation:

  • Abstraction: Order is an interface defining business rules.
  • Implementation: ConcreteOrder provides the calculation logic.
  • Dependency Inversion: printTotal depends on the abstract Order, not concrete details.

Chapter 16: Independence

Key Concepts:
  1. Component Independence:
    • Deployability: Components can be deployed separately (e.g., microservices).
    • Developability: Teams work independently on components.
    • Replaceability: Swap implementations without breaking the system.
  2. Decoupling Techniques:
    • Dependency Inversion: Depend on abstractions, not concretions.
    • Interface Segregation: Split interfaces to avoid unnecessary dependencies.
    • Boundary Patterns: Use layers, ports/adapters, or hexagonal architecture.
Code Example: Dependency Inversion & Interfaces:
#include <iostream>
#include <memory>// Abstraction (Port)
class Database {
public:virtual void save(const std::string& data) = 0;virtual ~Database() = default;
};// Low-level Detail (Adapter)
class SQLDatabase : public Database {
public:void save(const std::string& data) override {std::cout << "Saving to SQL: " << data << std::endl;}
};// High-level Policy
class UserService {
private:std::unique_ptr<Database> db;
public:UserService(std::unique_ptr<Database> db) : db(std::move(db)) {}void createUser(const std::string& name) {db->save("User: " + name);}
};int main() {auto sqlDb = std::make_unique<SQLDatabase>();UserService service(std::move(sqlDb));service.createUser("Alice"); // Output: Saving to SQL: User: Alicereturn 0;
}

Explanation:

  • Dependency Inversion: UserService depends on the Database abstraction.
  • Testability: Easily swap SQLDatabase with a MockDatabase for testing.
  • Decoupling: Changes to the database implementation don’t affect UserService.

Combined Example: Boundaries & Independence

#include <iostream>
#include <memory>// Port (Interface)
class PaymentGateway {
public:virtual void pay(double amount) = 0;virtual ~PaymentGateway() = default;
};// Adapter 1: PayPal Implementation
class PayPalGateway : public PaymentGateway {
public:void pay(double amount) override {std::cout << "Paying $" << amount << " via PayPal." << std::endl;}
};// Adapter 2: Stripe Implementation
class StripeGateway : public PaymentGateway {
public:void pay(double amount) override {std::cout << "Paying $" << amount << " via Stripe." << std::endl;}
};// High-level Policy
class OrderService {
private:std::unique_ptr<PaymentGateway> gateway;
public:OrderService(std::unique_ptr<PaymentGateway> gateway) : gateway(std::move(gateway)) {}void processOrder(double amount) {gateway->pay(amount);}
};int main() {// Swap payment gateways without changing OrderService.auto paypal = std::make_unique<PayPalGateway>();OrderService service1(std::move(paypal));service1.processOrder(100.0); // Output: Paying $100 via PayPal.auto stripe = std::make_unique<StripeGateway>();OrderService service2(std::move(stripe));service2.processOrder(200.0); // Output: Paying $200 via Stripe.return 0;
}

Explanation:

  • Boundary: PaymentGateway defines a port for payment processing.
  • Independence: OrderService is decoupled from specific payment providers.
  • Flexibility: New gateways (e.g., BitcoinGateway) can be added without modifying core logic.

Key Takeaways:

  1. Architecture = Managed Dependencies: Use abstractions to isolate volatility.
  2. Delay Decisions: Keep infrastructure (databases, UIs) replaceable.
  3. Test with Mocks: Compile-time polymorphism enables testing without concrete dependencies.

Chapters 15 & 16 Overview

Chapter 15: “What Is Architecture?”

  • Focuses on defining architecture as the structure of components, their relationships, and design principles guiding evolution.
  • Key topics:
    1. Architectural goals: Managing dependencies between components, enabling flexibility, and delaying decisions.
    2. Impact on development phases: Deployment, operation, maintenance, and evolution.
    3. Device independence and avoiding premature commitment to frameworks/databases.

Chapter 16: “Independence”

  • Discusses designing systems to achieve independent components for flexibility and scalability.
  • Key topics:
    1. Horizontal vs. vertical decoupling: Separating use cases, layers (UI, business logic, data).
    2. Delaying decisions: Keeping options open by abstracting volatile components (e.g., databases).
    3. Avoiding duplication while balancing decoupling.

10 Hard Difficulty Multiple-Choice Questions

Question 1
Which are core goals of software architecture according to Chapter 15?
A) Maximize code performance.
B) Delay irreversible decisions.
C) Enforce strict coding standards.
D) Manage dependencies between components.


Question 2
What does “device independence” imply in Clean Architecture?
A) Code must run on all hardware without modification.
B) Business logic should not depend on specific I/O devices or frameworks.
C) Use cross-platform libraries for all components.
D) Avoid using third-party APIs.


Question 3
Which principle helps achieve independent deployability of components?
A) Stable Dependencies Principle.
B) Interface Segregation Principle.
C) Single Responsibility Principle.
D) Common Closure Principle.


Question 4
Why is horizontal layering insufficient for true independence?
A) It enforces rigid dependencies between layers.
B) It doesn’t address vertical use-case boundaries.
C) It increases deployment complexity.
D) It violates the Open-Closed Principle.


Question 5
How does Clean Architecture handle database dependencies?
A) Business logic directly depends on SQL queries.
B) Database access is abstracted via interfaces.
C) Use a single global database connection.
D) Business logic and database are tightly coupled.


Question 6
Which is a valid strategy to delay decisions?
A) Hardcoding configuration values.
B) Using dependency injection for volatile components.
C) Relying on concrete framework APIs.
D) Embedding business rules in UI code.


Question 7
What is the risk of violating the Stable Dependencies Principle?
A) High-level policies depend on low-level details.
B) Components cannot be tested independently.
C) Changes propagate unpredictably across the system.
D) Code duplication increases.


Question 8
Which code snippet aligns with Clean Architecture principles?
Snippet 1:

class PaymentProcessor:def __init__(self, db_conn):self.db = db_conndef process(self, amount):self.db.execute("INSERT INTO payments ...")

Snippet 2:

class PaymentGateway(ABC):@abstractmethoddef process_payment(self, amount): passclass SqlPaymentGateway(PaymentGateway):def __init__(self, db_conn): ...def process_payment(self, amount): ...

A) Only Snippet 1.
B) Only Snippet 2.
C) Both.
D) Neither.


Question 9
What problem arises when business logic depends on UI frameworks?
A) UI changes force business logic rewrites.
B) Business logic becomes reusable across UIs.
C) It simplifies testing.
D) It improves deployment speed.


Question 10
Which is an example of vertical decoupling?
A) Separating code into MVC layers.
B) Isolating payment processing from user management.
C) Using interfaces for database access.
D) Implementing a plugin architecture.


Answers & Explanations

Answer 1
Correct: B, D
Explanation:

  • B) Delaying decisions prevents premature commitments (Ch15).
  • D) Managing dependencies is a core architectural goal (Ch15).
  • A) Performance is secondary to structural goals.
  • C) Coding standards are implementation details, not architectural goals.

Answer 2
Correct: B
Explanation:

  • B) Device independence means business logic isn’t tied to specific I/O (Ch15).
  • A) Code may require device-specific drivers but abstracts them.
  • C/D) Irrelevant to the core concept.

Answer 3
Correct: A
Explanation:

  • A) Stable Dependencies Principle ensures components depend only on stable abstractions (Ch16).
  • B/C/D) Address cohesion or interface design, not deployability.

Answer 4
Correct: B
Explanation:

  • B) Horizontal layers (e.g., UI, business logic) don’t isolate use cases vertically (Ch16).
  • A) Rigid dependencies are a symptom, not the root cause.

Answer 5
Correct: B
Explanation:

  • B) Abstracting database access via interfaces decouples business logic (Ch15).
  • A/C/D) Create tight coupling and violate independence.

Answer 6
Correct: B
Explanation:

  • B) Dependency injection defers concrete implementation choices (Ch16).
  • A/C/D) Fix decisions early, reducing flexibility.

Answer 7
Correct: A, C
Explanation:

  • A) High-level components depending on low-level details creates fragility.
  • C) Violations cause cascading changes (Ch16).
  • B/D) Unrelated to dependency stability.

Answer 8
Correct: B
Explanation:

  • Snippet 2 uses abstraction (PaymentGateway), aligning with DIP (Ch11/15).
  • Snippet 1 directly depends on a database, violating decoupling.

Answer 9
Correct: A
Explanation:

  • A) Tight coupling forces rewrites when UI changes (Ch16).
  • B/D) Independence improves reusability and deployment.

Answer 10
Correct: B
Explanation:

  • B) Vertical decoupling isolates use cases (e.g., payment vs. user management) (Ch16).
  • A/C) Horizontal layering or interface use.
  • D) Plugin architecture is a horizontal strategy.

Test Code Examples

Example for Q8 (Snippet 2):

from abc import ABC, abstractmethodclass PaymentGateway(ABC):@abstractmethoddef process_payment(self, amount): passclass SqlPaymentGateway(PaymentGateway):def __init__(self, db_conn):self.db = db_conndef process_payment(self, amount):self.db.execute("INSERT INTO payments ...")# Test
class MockDb:def execute(self, query): print(f"Mock: {query}")gateway = SqlPaymentGateway(MockDb())
gateway.process_payment(100)  # Output: "Mock: INSERT INTO payments ..."

Compilation: This Python code runs as-is, demonstrating dependency inversion.

Example for Q5:

class DatabaseInterface(ABC):@abstractmethoddef save_payment(self, amount): passclass PostgresAdapter(DatabaseInterface):def save_payment(self, amount): ...class BusinessLogic:def __init__(self, db: DatabaseInterface):self.db = dbdef process_payment(self, amount):self.db.save_payment(amount)

Test: BusinessLogic depends on an abstraction, enabling database swaps without code changes.


http://www.ppmy.cn/server/180633.html

相关文章

Postman 版本信息速查:快速定位版本号

保持 Postman 更新至最新版本是非常重要的&#xff0c;因为这能让我们享受到最新的功能&#xff0c;同时也保证了软件的安全性。所以&#xff0c;如何快速查看你的 Postman 版本信息呢&#xff1f; 如何查看 Postman 的版本信息教程

unity中Xcharts图表鼠标悬浮表现异常

鼠标悬浮在面板附近&#xff0c;只显示单独的一个项目 而且无论鼠标如何移动&#xff0c;根本没有效果。 解决方案&#xff1a; 需要在对应的Canvas上绑定主相机才可以 鼠标移动到项目上就有信息展示了

基于javaweb的SpringBoot实验室管理系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

【STM32】WDG看门狗(学习笔记)

学习来源----->江协科技STM32 WDG简介 WDG&#xff08;Watchdog&#xff09;看门狗看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入长…

18.OpenCV图像卷积及其模糊滤波应用详解

OpenCV图像卷积及其模糊滤波应用详解 在图像处理领域&#xff0c;卷积是一种非常基础且强大的操作。它通过将一个小矩阵&#xff08;称为卷积核或滤波器&#xff09;滑动覆盖在图像上&#xff0c;对每个像素进行加权求和&#xff0c;从而实现图像的平滑、边缘检测、锐化、模糊等…

解锁科研绘图新姿势:DeepSeek 携手 Rstudio 绘图可视化

在科研领域&#xff0c;数据可视化至关重要&#xff0c;它能直观呈现复杂数据&#xff0c;助力科研成果展示与交流。本文深入探讨如何借助DeepSeek结合Rstudio绘制8种常见科研图表&#xff0c;详细阐述每种图表的绘制指令、代码解读、参数调整以及实际应用场景&#xff0c;为科…

爱因斯坦求和 torch

目录 向量点积 矩阵乘法 矩阵转置 向量转换相机坐标系 在 Python 的科学计算库&#xff08;如 NumPy&#xff09;中&#xff0c;einsum 是一个强大的函数&#xff0c;它可以简洁地表示各种张量运算。下面是几个不同类型的使用示例&#xff1a; 向量点积 向量点积是两个向量…

HTML5 Canvas绘画板项目实战:打造一个功能丰富的在线画板

HTML5 Canvas绘画板项目实战&#xff1a;打造一个功能丰富的在线画板 这里写目录标题 HTML5 Canvas绘画板项目实战&#xff1a;打造一个功能丰富的在线画板项目介绍技术栈核心功能实现1. 画板初始化与工具管理2. 多样化绘画工具3. 事件处理机制 技术要点分析1. Canvas上下文优化…