Chapter 5 - Design Principles Flashcards
abstractions
a simplified representation of a given entity
Functions, classes, interfaces, and packages are classic abstractions provided by programming languages
What is the primary objective of software design?
to decompose a problem into smaller parts
design principles
guidelines for ensuring that a design meets the aforementioned properties
design properties
conceptual integrity, information hiding, cohesion, and coupling
Conceptual integrity
facilitates system usage and comprehension. When we follow this property, a user familiar with one part of a system feels comfortable using another part, as the features and user interface remain consistent.
Information hiding
offers the following advantages to a software project: Parallel development, Changeability, Comprehensibility
interface
class’s public members
Cohesion
each class should fulfill a single function or service. Specifically, all methods and attributes of a class should contribute to the implementation of the same service
Separation of concerns
recommends that a class should implement only one concern. In this context, concern refers to any functionality, requirement, or responsibility of the class.
Coupling
the strength of the connection between two modules
acceptable coupling
between class A and class B when:
- Class A only uses public methods from class B.
- The interface provided by B is stable, both syntactically and semantically. This means that the signatures of B’s public methods do not change frequently, and neither does the behavior of these methods. As a result, changes in B will rarely impact A.
poor coupling
between class A and B when changes in B can easily impact A.
- When classes A and B share global variables or data structures, for instance, when B changes the value of a global variable used by A.
- When class A directly accesses a file or database used by class B.
- When B’s interface is not stable. For example, when the public methods of B are frequently renamed.
Structural Coupling
between A and B occurs when a class A has an explicit reference in its code to a class B.
For example, the coupling between ParkingLot and Hashtable is structural
Evolutionary (or Logical) Coupling
between A and B occurs when changes in class B usually propagate to class A.
Thus, in Example 2, where class A depends on an integer stored in a file maintained by B, there is an evolutionary coupling between A and B. For instance, changes in the file format would have an impact on A.
SOLID Principles
Single Responsibility Principle
Open Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle
Single Responsibility Principle
This principle is an application of the idea of cohesion. It proposes that every class should have a single responsibility.
presentation
a system should have presentation classes, which implement the interface with users
business logic
classes perform computations directly related to the solution domain
Interface Segregation Principle
The principle states that interfaces should be small, cohesive, and, more importantly, specific to each type of client. Its aim is to prevent clients from depending on interfaces with many methods they won’t use.
Dependency Inversion Principle
This principle advocates that client classes should primarily depend on abstractions rather than on concrete implementations, as abstractions (i.e., interfaces) tend to be more stable than concrete implementations (i.e., classes).
Prefer Composition Over Inheritance
the principle does not prohibit the use of inheritance. It merely suggests that when faced with two design solutions—one based on inheritance and the other on composition—the latter is generally preferable
Class inheritance
(example: class A extends B) involves code reuse
Interface inheritance
(example: interface I extends J) does not involve code reuse
composition
exists when a class A contains an attribute whose type is another class B.
Demeter Principle
asserts that a method’s implementation should only invoke methods:
From its own class (case 1)
From objects received as parameters (case 2)
From objects created by the method itself (case 3)
From attributes of the method’s class (case 4)
Open-Closed Principle
core concept is that developers should not only implement a class, but also prepare it for future extensions and customizations. To achieve this, they can use parameters, inheritance, higher-order (or lambda) functions, and design patterns
Liskov Substitution Principle
establishes rules for redefining methods in subclasses