도구 태그
SOLID 클래스의 원리 SOLID
SOLID
SOLID 는 기억하기 쉬운 약어입니다. Robert Martin이 명명한 5가지 가장 중요한 객체 지향 코딩 설계 원칙을 나타내는 Michael Feathers 작성SOLID 是Michael Feathers推荐的便于记忆的首字母简写,它代表了Robert Martin命名的最重要的五个面对对象编码设计原则
S: 单一职责原则 (SRP)
O: 开闭原则 (OCP)
L: 里氏替换原则 (LSP)
I: 接口隔离原则 (ISP)
D: 依赖倒置原则 (DIP)
1. 单一职责原则
Single Responsibility Principle (SRP)
正如在Clean Code所述,"修改一个类应该只为一个理由"。 人们总是易于用一堆方法塞满一个类,如同我们只能在飞机上 只能携带一个行李箱(把所有的东西都塞到箱子里)。这样做 的问题是:从概念上这样的类不是高内聚的,并且留下了很多 理由去修改它。将你需要修改类的次数降低到最小很重要。 这是因为,当有很多方法在类中时,修改其中一处,你很难知 晓在代码库中哪些依赖的模块会被影响到。
坏:
class UserSettings
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function changeSettings(array $settings): void
{
if ($this->verifyCredentials()) {
// ...
}
}
private function verifyCredentials(): bool
{
// ...
}
}好:
class UserAuth
{
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function verifyCredentials(): bool
{
// ...
}
}
class UserSettings
{
private $user;
private $auth;
public function __construct(User $user)
{
$this->user = $user;
$this->auth = new UserAuth($user);
}
public function changeSettings(array $settings): void
{
if ($this->auth->verifyCredentials()) {
// ...
}
}
}2. 开闭原则
Open/Closed Principle (OCP)
正如Bertrand Meyer所述,"软件的工件( classes, modules, functions 等) 应该对扩展开放,对修改关闭。" 然而这句话意味着什么呢?这个原则大体上表示你 应该允许在不改变已有代码的情况下增加新的功能
坏:
abstract class Adapter
{
protected $name;
public function getName(): string
{
return $this->name;
}
}
class AjaxAdapter extends Adapter
{
public function __construct()
{
parent::__construct();
$this->name = 'ajaxAdapter';
}
}
class NodeAdapter extends Adapter
{
public function __construct()
{
parent::__construct();
$this->name = 'nodeAdapter';
}
}
class HttpRequester
{
private $adapter;
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
}
public function fetch(string $url): Promise
{
$adapterName = $this->adapter->getName();
if ($adapterName === 'ajaxAdapter') {
return $this->makeAjaxCall($url);
} elseif ($adapterName === 'httpNodeAdapter') {
return $this->makeHttpCall($url);
}
}
private function makeAjaxCall(string $url): Promise
{
// request and return promise
}
private function makeHttpCall(string $url): Promise
{
// request and return promise
}
}好:
interface Adapter
{
public function request(string $url): Promise;
}
class AjaxAdapter implements Adapter
{
public function request(string $url): Promise
{
// request and return promise
}
}
class NodeAdapter implements Adapter
{
public function request(string $url): Promise
{
// request and return promise
}
}
class HttpRequester
{
private $adapter;
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
}
public function fetch(string $url): Promise
{
return $this->adapter->request($url);
}
}
3. 里氏替换原则
Liskov Substitution Principle (LSP)
- S: 단일 책임 원칙(SRP)
< /li>
- O: 개방-폐쇄 원칙(OCP)🎜
- 🎜L: 리스코프 대체 원칙(LSP)🎜 li>
- 🎜I: 인터페이스 분리 원칙(ISP) 🎜
- 🎜D: 종속성 역전 원칙(DIP)🎜
단일 책임 원칙( SRP)🎜🎜Clean Code에 명시된 것처럼 "클래스를 수정하는 이유는 한 가지여야 합니다." 비행기에 여행가방 하나만 가지고 다닐 수 있는 것처럼(모든 것을 여행가방에 담는다) 클래스에 여러 메서드를 채우는 것은 항상 쉽습니다. 문제는 개념적으로 그러한 클래스가 응집력이 높지 않고 수정해야 할 이유가 많다는 것입니다. 클래스를 수정해야 하는 횟수를 최소화하는 것이 중요합니다. 클래스에 여러 개의 메서드가 있는 경우 그 중 하나를 수정하면 코드 베이스의 어떤 종속 모듈이 영향을 받을지 알기 어렵기 때문입니다. 🎜🎜나쁨:🎜class Rectangle
{
protected $width = 0;
protected $height = 0;
public function setWidth(int $width): void
{
$this->width = $width;
}
public function setHeight(int $height): void
{
$this->height = $height;
}
public function getArea(): int
{
return $this->width * $this->height;
}
}
class Square extends Rectangle
{
public function setWidth(int $width): void
{
$this->width = $this->height = $width;
}
public function setHeight(int $height): void
{
$this->width = $this->height = $height;
}
}
function printArea(Rectangle $rectangle): void
{
$rectangle->setWidth(4);
$rectangle->setHeight(5);
// BAD: Will return 25 for Square. Should be 20.
echo sprintf('%s has area %d.', get_class($rectangle), $rectangle->getArea()).PHP_EOL;
}
$rectangles = [new Rectangle(), new Square()];
foreach ($rectangles as $rectangle) {
printArea($rectangle);
}🎜좋음:🎜interface Shape
{
public function getArea(): int;
}
class Rectangle implements Shape
{
private $width = 0;
private $height = 0;
public function __construct(int $width, int $height)
{
$this->width = $width;
$this->height = $height;
}
public function getArea(): int
{
return $this->width * $this->height;
}
}
class Square implements Shape
{
private $length = 0;
public function __construct(int $length)
{
$this->length = $length;
}
public function getArea(): int
{
return $this->length ** 2;
}
}
function printArea(Shape $shape): void
{
echo sprintf('%s has area %d.', get_class($shape), $shape->getArea()).PHP_EOL;
}
$shapes = [new Rectangle(4, 5), new Square(5)];
foreach ($shapes as $shape) {
printArea($shape);
}🎜🎜2. 개방/폐쇄 원칙🎜🎜🎜개방/폐쇄 원칙(OCP)🎜🎜Bertrand Meyer가 말했듯이 "소프트웨어의 아티팩트( 클래스, 모듈, 함수 등)는 확장을 위해 열려 있어야 하고 수정을 위해 닫혀 있어야 합니다." 문장은 무엇을 의미합니까? 이 원칙은 일반적으로 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있도록 허용해야 함을 의미합니다. 🎜🎜나쁨:🎜interface Employee
{
public function work(): void;
public function eat(): void;
}
class HumanEmployee implements Employee
{
public function work(): void
{
// ....working
}
public function eat(): void
{
// ...... eating in lunch break
}
}
class RobotEmployee implements Employee
{
public function work(): void
{
//.... working much more
}
public function eat(): void
{
//.... robot can't eat, but it must implement this method
}
}🎜좋음:🎜interface Workable
{
public function work(): void;
}
interface Feedable
{
public function eat(): void;
}
interface Employee extends Feedable, Workable
{
}
class HumanEmployee implements Employee
{
public function work(): void
{
// ....working
}
public function eat(): void
{
//.... eating in lunch break
}
}
// robot can only work
class RobotEmployee implements Workable
{
public function work(): void
{
// ....working
}
}🎜 🎜🎜< a name=" 3">🎜3.리스코프 대체 원리🎜🎜리스코프 대체 원리(LSP)🎜🎜간단한 원리이지만 이해하기 어려운 용어를 사용하고 있습니다. 공식적인 정의는 "S가 T의 하위 유형인 경우 프로그램의 원래 설정된 속성(검사, 작업 실행 등)을 변경하지 않고 T 유형의 모든 객체를 S 유형의 객체로 대체할 수 있습니다(예: S 객체를 사용하면 T) 객체를 대체할 수 있습니다." 이 정의는 이해하기가 더 어렵습니다 :-). 🎜이 개념에 대한 가장 좋은 설명은 부모 클래스와 자식 클래스가 있는 경우 원래 결과의 정확성을 변경하지 않고 부모 클래스와 자식 클래스를 교환할 수 있다는 것입니다. 여전히 다소 혼란스럽게 들리므로 고전적인 정사각형-직사각형 예를 살펴보겠습니다. 수학적으로 정사각형은 직사각형이지만 모델이 상속을 통해 "is-a" 관계를 사용하는 경우에는 그렇지 않습니다.
나쁨:
class Employee
{
public function work(): void
{
// ....working
}
}
class Robot extends Employee
{
public function work(): void
{
//.... working much more
}
}
class Manager
{
private $employee;
public function __construct(Employee $employee)
{
$this->employee = $employee;
}
public function manage(): void
{
$this->employee->work();
}
}좋음:
이 두 가지 유형의 쿼드를 별도로 처리하고 두 유형 모두에 맞는 보다 일반적인 하위 유형으로 대체하는 것이 좋습니다.
정사각형과 직사각형은 비슷해 보이지만 다릅니다. 정사각형은 마름모에 더 가깝고 직사각형은 평행사변형에 더 가깝습니다. 그러나 그들은 하위 유형이 아닙니다. 유사하지만 정사각형, 직사각형, 마름모, 평행사변형은 모두 고유한 특성을 지닌 서로 다른 모양입니다.
interface Employee
{
public function work(): void;
}
class Human implements Employee
{
public function work(): void
{
// ....working
}
}
class Robot implements Employee
{
public function work(): void
{
//.... working much more
}
}
class Manager
{
private $employee;
public function __construct(Employee $employee)
{
$this->employee = $employee;
}
public function manage(): void
{
$this->employee->work();
}
}4. 인터페이스 분리 원칙
인터페이스 분리 원칙(ISP)Interface Segregation Principle (ISP)
接口隔离原则表示:"调用方不应该被强制依赖于他不需要的接口"
有一个清晰的例子来说明示范这条原则。当一个类需要一个大量的设置项, 为了方便不会要求调用方去设置大量的选项,因为在通常他们不需要所有的 设置项。使设置项可选有助于我们避免产生"胖接口"
坏:
rrreee好:
不是每一个工人都是雇员,但是每一个雇员都是一个工人
rrreee5. 依赖倒置原则
Dependency Inversion Principle (DIP)
나쁨:
rrreee
좋음:
모든 직원이 직원은 아니지만 모든 직원은 직원입니다rrreee< a name="5"> 5. 종속성 역전 원칙
종속성 역전 원칙(DIP)
관련 동영상
핫 AI 도구
무료로 이미지를 벗다
사진에서 옷을 제거하는 온라인 AI 도구입니다.
사실적인 누드 사진을 만들기 위한 AI 기반 앱
더 현명한 결정을 위한 AI 기반 투자 연구
인기 기사
뜨거운 주제
20459
7
13602
4
11942
4
8945
17
8487
7
인기 있는 도구
사용하기 쉬운 무료 코드 편집기
중국어 버전, 사용하기 매우 쉽습니다.
강력한 PHP 통합 개발 환경
시각적 웹 개발 도구
신 수준의 코드 편집 소프트웨어(SublimeText3)












![PHP 실용 개발 시작하기: 빠른 PHP 생성 [중소기업 포럼]](https://img.php.cn/upload/course/000/000/035/5d27fb58823dc974.jpg)
