SoC -- the root design principle
Separation of Concerns -- Root Principle
https://effectivesoftwaredesign.com/2012/02/05/separation-of-concerns/
道生一,一生二
混沌世界初开时候,为一团气体,
盘古开天辟地之后, 轻气上扬, 浊气下沉。
类似软件世界,软件是现实世界的模拟。
软件的发展,也从最开始的单体个文件, 出现需要划分模块的情况;
实际上模块的出现就是为管理软件的复杂度, 将相关的逻辑内聚在同一模块内, 将无关的逻辑解耦到不同的模块。
类似机器学习中的聚类算法。
达到的一个特征:
高内聚
低耦合
The most important principle in Software Engineering is the Separation of Concerns (SoC): The idea that a software system must be decomposed into parts that overlap in functionality as little as possible. It is so central that it appears in many different forms in the evolution of all methodologies, programming languages and best practices.
Since the first software systems were implemented, it was understood that it was important for them to be modular. It is necessary to follow a methodology when decomposing a system into modules and this is generally done by focusing on the software quality metrics of coupling and cohesion, originally defined by Constantine:
Coupling: The degree of dependency between two modules. We always want low coupling.
Cohesion: The measure of how strongly-related is the set of functions performed by a module. We always want high cohesion.
SoC 优点
https://nalexn.github.io/separation-of-concerns/
优点
- 代码更加清晰
- 复用性更好
- 更好的测试性
- 项目快速演进
- 更好组织并行开发
Benefits of the Loose Coupling and High Cohesion
Adherence to the principle of Separation of Concerns helps to improve numerous characteristics of the codebase:
- Better code clarity. It is much easier to understand what is going on in the program when each module has a concise and clear API with a logically scoped set of methods.
- Better code reusability (DRY principle). The main benefit of reusing the code is reduced maintenance costs. Whenever you need to extend the functionality or fix a bug - it’s much less painful to do when you’re certain it appears in one place only.
- Better testability. Independent modules with properly scoped functionality and isolation from the rest of the app are a breeze to test. You don’t need to set up the entire environment to see how your module works - it is sufficient to replace neighboring real modules with dummy mocks or fake data sources. This way you can test the module as the black box by verifying just the output, or as the white box by also seeing which methods are being called on the connected modules (BDD).
- Faster project evolution. Whether it’s a new feature or an update of the existing one, isolation of the modules helps with scoping out the areas of the program that may be affected by the change, thus speeding up the development.
- It is easier to organize simultaneous development by multiple engineers. They just need to agree on which module they are working on to make sure they don’t interfere with each other. Only the update of a module’s API can be a flag for explicit notifying other developers, while most of the changes can be added without immediate attention from the other contributors. When coupled with good test coverage, the parallel development becomes as efficient as the cumulative productivity of each individual engineer working solely (it is usually slower).
As you can see, coupling and cohesion are the characteristics that ultimately affect the convenience of working with the code from the programmer’s perspective.
SoC 风格
http://aspiringcraftsman.com/2008/01/03/art-of-separation-of-concerns/
软件模块的水平切分
Horizontal Separation
Horizontal Separation of Concerns refers to the process of dividing an application into logical layers of functionally that fulfill the same role within the application.
One common division for graphical user interface applications is the separation of processes into the layers of Presentation, Business, and Resource Access. These categories encompass the main types of concerns for most application needs, and represent an organization of concerns which minimizes the level of dependencies within an application. Figure 1 depicts a typical three-layered application:
软件模块的竖直切分
Vertical Separation
Vertical Separation of Concerns refers to the process of dividing an application into modules of functionality that relate to the same feature or sub-system within an application. Vertical separation divides the features of an application holistically, associating any interface, business, and resource access concerns within a single boundary. Figure 3 depicts an application separated into three modules:
方面分离, 交叉切分, 将附属模块从 主模块中隔离开来, 例如 日志模块, 被所有模块调用, 但是其不属于任意模块。
Aspect Separation
Aspect Separation of Concerns, better known as Aspect-Oriented Programming, refers to the process of segregating an application’s cross-cutting concerns from its core concerns. Cross-cutting concerns, or aspects, are concerns which are interspersed across multiple boundaries within an application. Logging is one example of an activity performed across many system components.
Figure 7 depicts an application with several cross-cutting concerns:
依赖方向定义
Dependency Direction
One characteristic of good Separation of Concerns is the ideal establishment of dependency direction. An ideal dependency direction establishes the roles of consumer and dependency such that the role of dependency is occupied by the entity possessing the highest potential for reuse.
Because the function of caching is a more generic behavior than an order inquiry process, the caching component has the higher potential for reuse among the two. Therefore, the best dependency direction in this case would be from the business component to the utility component. This dependency is depicted in Figure 9:
数据层抽离
Data Concerns
Applying the principle of Separation of Concerns to data involves properly modeling information managed by a system. While the aspects of data modeling apply to both object-oriented and database design, this discussion focuses on object-oriented data concerns since the primary needs of a database often require form to follow function.
行为层抽离
Behavior Concerns
Separating behavior involves the division of system processes into logical, manageable, and reusable units of code. This represents the most fundamental type of Separation of Concerns. Within object-oriented systems, fine-grained behavior is separated using methods while course-grained behavior is separated using objects, components, applications, and services.
模块的切分需要关注扩展性
Extending Concerns
Extensions are a separation of concerns strategy which enables the addition of new behavior to an existing set of concerns. Extensions are used to enhance existing concerns where the desired behavior cannot be added to the targeted system, is not an inherent behavior of the system, or is otherwise impractical for inclusion as part of the system’s core set of features. Figure 10 depicts the dependency relationship of an extension to a target system:
代理模块
Delegating Concerns
Delegating concerns refers to the process of assigning the responsibility for fulfilling behavior to a subordinate component. This strategy separates the concerns of responsibility from execution, and is beneficial for designing components whose implementation details may vary depending on external conditions. Using this strategy, components proxy some or all data requests and method invocations to another component designed to fulfill the request in a specialized way. For example, a component designed to return a list of roles assigned to the current user may delegate the request to one or more subordinate components designed to retrieve roles from a local XML file, database, and/or a remote service. Figure 11 illustrates the delegation of authorization concerns to components specialized for differing data sources:
Delegation can be facilitated using the Strategy Pattern, the Plug-in Pattern, the Microsoft Provider Model, and other variant patterns which enable portions of a component’s behavior to be fulfilled externally.
控制反转关注, 上层抽象和 具体实现 的分离。
Inverting Concerns
Inverting concerns, better known as Inversion of Control, refers to the process of moving a concern outside of an established boundary. Some uses for inversion of concerns include effecting aspect separation, minimizing non-essential processes, decoupling components from specific abstraction strategies, or relocating responsibilities to infrastructure components. Some specific applications would include alleviating responsibilities pertaining to hardware interaction, work-flow management, registration processes, or obtaining dependencies.
Figure 12 depicts an inversion of concerns process where both a presentation component and a domain component have had concerns moved to infrastructure level components: