(ARTICLE): Finished writing the I.
This commit is contained in:
parent
b40934a72e
commit
467186f94e
@ -20,7 +20,7 @@ maintainable and extensible software. Adapting these principles into your own co
|
|||||||
[code smells](https://en.wikipedia.org/wiki/Code_smell), refactor code and develop Agile software.
|
[code smells](https://en.wikipedia.org/wiki/Code_smell), refactor code and develop Agile software.
|
||||||
|
|
||||||
>
|
>
|
||||||
> "If you think good architecture is expensive, try bad architecture." ~Uncle Bob
|
> "If you think good architecture is expensive, try bad architecture." ~Robert "Uncle Bob" Martin
|
||||||
>
|
>
|
||||||
|
|
||||||
The five principles are as follows:
|
The five principles are as follows:
|
||||||
@ -462,15 +462,112 @@ because the settings are being overridden, and each value is set individually fr
|
|||||||
expectation for a rectangle is that the height and width will be set independently!
|
expectation for a rectangle is that the height and width will be set independently!
|
||||||
|
|
||||||
## Interface Segregation Principle
|
## Interface Segregation Principle
|
||||||
define the rule
|
|
||||||
why it exists
|
|
||||||
what is attempts to achieve
|
|
||||||
|
|
||||||
|
The interface segregation principle states:
|
||||||
|
|
||||||
|
>
|
||||||
|
> "A client should never be forced to implement an interface that it doesn’t use, or clients
|
||||||
|
> shouldn’t be forced to depend on methods they do not use." ~Robert "Uncle Bob" Martin
|
||||||
|
>
|
||||||
|
|
||||||
|
The goal of the interface segregation principle (ISP) is that large, general-purpose interfaces should
|
||||||
|
be broken down into smaller, **more specific** interfaces. Doing so means that client classes only need
|
||||||
|
to be aware of the methods that are directly relevant to them.
|
||||||
|
|
||||||
|
### Code Example
|
||||||
|
|
||||||
|
Imagine a scenario where we have various types of printers, such as simple, multifunctional, and
|
||||||
|
others. We create a single, large interface, `IMachine`, that attempts to encompass all the functionality.
|
||||||
|
This multi-use interface is what's known as a **[fat interface](https://dev.to/mcsee/code-smell-216-fat-interface-3jlp)**.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// VIOLATION: A single, "fat" interface with methods not all clients need.
|
||||||
|
class IMachine {
|
||||||
|
public:
|
||||||
|
virtual void print(const std::string& document) const = 0;
|
||||||
|
virtual void scan(const std::string& document) const = 0;
|
||||||
|
virtual void fax(const std::string& document) const = 0;
|
||||||
|
virtual ~IMachine() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A SimplePrinter only needs to print, but it is forced to implement scan and fax.
|
||||||
|
class SimplePrinter : public IMachine {
|
||||||
|
public:
|
||||||
|
void print(const std::string& document) const override {
|
||||||
|
std::cout << "SimplePrinter: Printing " << document << ".\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROBLEM: SimplePrinter is forced to implement methods it doesn't use.
|
||||||
|
void scan(const std::string& document) const override {
|
||||||
|
// This implementation is a lie/waste, or throws an exception.
|
||||||
|
std::cerr << "SimplePrinter: ERROR! Cannot scan.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void fax(const std::string& document) const override {
|
||||||
|
// This forces unnecessary dependencies and potential runtime errors.
|
||||||
|
std::cerr << "SimplePrinter: ERROR! Cannot fax.\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
The `SimplePrinter` is forced to implement the `scan` and `fax` methods, which are functions the printer
|
||||||
|
does not have, therefore violating the LSP! However, a simple fix exists: **splitting the interface
|
||||||
|
into separate interfaces.**
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// 1. Segregated Interface: Printing capability
|
||||||
|
class IPrinter {
|
||||||
|
public:
|
||||||
|
virtual void print(const std::string &document) const = 0;
|
||||||
|
virtual ~IPrinter() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Segregated Interface: Scanning capability
|
||||||
|
class IScanner {
|
||||||
|
public:
|
||||||
|
virtual void scan(const std::string &document) const = 0;
|
||||||
|
virtual ~IScanner() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3. Segregated Interface: Fax capability
|
||||||
|
class IFaxDevice {
|
||||||
|
public:
|
||||||
|
virtual void fax(const std::string &document) const = 0;
|
||||||
|
virtual ~IFaxDevice() = default;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the interfaces have been *thinned*, we can implement them again, but this time, in a way that
|
||||||
|
does not violate the ISP.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// ADHERENCE: SimplePrinter now only implements the interface it needs.
|
||||||
|
class SimplePrinterSRP : public IPrinter {
|
||||||
|
public:
|
||||||
|
void print(const std::string &document) const override {
|
||||||
|
std::cout << "SimplePrinter: Printing " << document << ".\n";
|
||||||
|
}
|
||||||
|
// No more forced scan or fax methods! The client is clean.
|
||||||
|
};
|
||||||
|
|
||||||
|
// The MultiFunctionPrinter implements ALL the needed interfaces (composition)
|
||||||
|
class MultiFunctionPrinter : public IPrinter,
|
||||||
|
public IScanner,
|
||||||
|
public IFaxDevice {
|
||||||
|
public:
|
||||||
|
void print(const std::string &document) const override {
|
||||||
|
std::cout << "MFP: Printing " << document << ".\n";
|
||||||
|
}
|
||||||
|
void scan(const std::string &document) const override {
|
||||||
|
std::cout << "MFP: Scanning " << document << ".\n";
|
||||||
|
}
|
||||||
|
void fax(const std::string &document) const override {
|
||||||
|
std::cout << "MFP: Faxing " << document << ".\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Dependency Inversion Principle
|
## Dependency Inversion Principle
|
||||||
define the rule
|
|
||||||
why it exists
|
|
||||||
what is attempts to achieve
|
|
||||||
|
|
||||||
## SOLID Only For OOP?
|
## SOLID Only For OOP?
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user