> Java > java지도 시간 > 본문

디자인 패턴의 7가지 원칙 요약

坏嘻嘻
풀어 주다: 2018-09-14 09:45:02
원래의
1689명이 탐색했습니다.

이 튜토리얼에서는 Java 예제를 통해 디자인 패턴의 개념을 단계별로 설명합니다.

1.단일 책임 원칙

목적: 코드 복잡성 감소, 시스템 분리 및 가독성 향상# 🎜🎜#
# 🎜🎜#

의미:

클래스의 경우 클래스를 변경하는 이유는 단 하나이며, 이 책임은 다른 클래스의 변경 원인입니다. 변화를 위해.

해결책:

다양한 책임을 다양한 클래스나 모듈에 캡슐화합니다. 기존 책임을 더 작은 단위의 책임으로 나누는 새로운 요구 사항이 있는 경우 기존 코드를 적시에 리팩터링해야 합니다. 시스템 로직이 충분히 단순하고, 메서드가 충분히 적고, 하위 클래스가 충분히 적거나, 후속 연결이 충분히 적다면, 과도한 설계와 과도한 세분성을 피하기 위해 SRP 원칙을 엄격하게 따를 필요가 없습니다.

예:

전선은 주민들에게 220v 전압의 전력을 공급하지만 새로운 수요가 증가했으며 전선은 200kv 전압의 고전압 전기도 전달합니다. 확장을 달성하기 위해 원래 와이어 방법을 추가할 수 있으며 이는 단일 책임 원칙을 위반합니다. 기본 클래스를 제공하고 주거용 전원 공급선과 고전압 전송선이라는 두 개의 파생 클래스를 생성할 수 있습니다. 2. 리스코프 대체 원칙

목적:

시스템 상속 시스템의 파괴를 피하기 위해#🎜 🎜##🎜 🎜#의미: 기본 클래스를 참조하는 모든 장소는 해당 하위 클래스의 개체를 투명하게 사용할 수 있어야 합니다.

해결책: 하위 클래스는 상위 클래스의 추상 메서드를 구현할 수 있지만 상위 클래스의 비추상 메서드를 재정의할 수는 없습니다. 하위 클래스는 고유한 메서드를 추가할 수 있습니다. 하위 클래스가 상위 클래스의 메서드를 재정의하거나 구현할 때 메서드의 전제 조건(즉, 메서드의 형식 매개변수)은 하위 클래스의 메서드가 구현될 때 상위 클래스 메서드의 입력 매개변수보다 느슨합니다. 부모 클래스의 추상 메서드, 메서드의 사후 조건 조건(즉, 메서드의 반환 값)은 부모 클래스의 조건보다 엄격합니다. 하위 클래스가 상위 클래스의 메서드를 완전히 구현할 수 없거나 상위 클래스의 일부 메서드가 하위 클래스에서 왜곡된 경우 상속 관계를 끊고 상속 대신 종속성, 집계, 조합 및 기타 관계를 사용하는 것이 좋습니다.

예: 은 새가 두 날개로 날 수 있는 방법을 정의했습니다. 새로 추가된 타조는 부모 클래스의 방법을 재정의하면 날지 않습니다. 이 방법에서 아무것도 하지 않으면 리히터 치환 원리를 위반하고 모든 새가 날지 못하게 됩니다. 비행 및 날지 못하는 두 가지 기본 새 클래스를 나란히 생성해야 합니다. 전제 조건은 더 느슨하고 사후 조건은 더 엄격합니다. 예를 들어 상위 클래스는 Map을 반환하고 하위 클래스는 HashMap을 반환합니다. 상위 클래스는 HashMap 형식 매개 변수를 허용하고 하위 클래스는 Map을 허용합니다.

3. 종속 역전 원칙

목적:

수요 변화로 인한 과도한 유지 관리 작업 방지

# 🎜🎜##🎜🎜 #의미:

상위 수준 모듈은 하위 수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 합니다. 세부 사항은 추상화에 의존해서는 안 됩니다.

해결책:

인터페이스 지향 프로그래밍, 인터페이스 또는 추상 클래스를 사용하여 특정 작업을 포함하지 않고 사양 및 계약을 공식화하고 세부 사항을 표시하는 작업을 그들에게 맡깁니다. 구현 완료할 수업.

예:

어머니 클래스에는 Book 클래스 입력에 의존하고 Book 클래스의 getContent 메서드를 사용하여 이야기를 전달하는 스토리텔링 메서드 TellStory가 있습니다. 그러면 다음 번에 엄마가 신문이나 휴대전화를 통해 이야기를 들려주어야 할 때 원래의 인터페이스는 무력해질 것입니다. 이때 getContent 메소드를 포함하는 IReader 기본 클래스가 추상화되고 Book, Newspaper, Cellphone이 별도로 구현됩니다. 어머니의 TellStory 메소드는 IReader 인스턴스를 승인하고 getContent 메소드를 호출합니다. 4. 인터페이스 분리 원칙

목적: 부풀어 오른 인터페이스 방지

#🎜 🎜#의미: #🎜 🎜#클라이언트는 필요하지 않은 인터페이스에 의존해서는 안 되며, 한 클래스가 다른 클래스에 의존하는 것은 가장 작은 인터페이스를 기반으로 해야 합니다.

해결책: 인터페이스를 적당히 다듬고 비대해진 인터페이스를 여러 개의 독립적인 인터페이스로 분할합니다.

예: 언어, 수학, 물리학, 화학, 생물학, 정치, 역사, 지리 등을 테스트하는 방법을 포함한 시험 인터페이스. 학생 클래스는 시험 인터페이스를 구현하고 시험에 응시합니다. 인문학 학생 클래스와 과학 학생 클래스는 학생 클래스에서 파생됩니다. 시험 인터페이스를 구현할 때 필요하지 않은 몇 가지 방법을 구현해야 합니다. (인문학 학생은 물리, 화학, 과학 시험을 치르지 않기 때문입니다.) 정치, 역사, 지리 시험은 치르지 않습니다.) 이때 시험 인터페이스를 세분화하여 기본 과목 시험 인터페이스, 교양 시험 인터페이스 및 과학 시험 인터페이스로 구분할 필요가 있습니다. 학생 수업은 기본 교과 시험 인터페이스와 과학 학생을 각각 구현합니다. 시험 인터페이스.

5. 데메테르 원칙

목적:

클래스 간 결합 감소

의미: 각 소프트웨어 단위는 다른 단위에 대한 최소한의 지식을 갖고 있으며 이 단위와 밀접하게 관련된 소프트웨어 단위로 제한됩니다.

해결책: 종속성, 연관, 조합, 집계 등 결합 관계가 없는 익숙하지 않은 클래스는 클래스 내부에 지역 변수로 표시되어서는 안 됩니다.

예: 교장은 교사를 관리하고 교사는 학생을 관리합니다. 교장은 모든 사람에게 전화해야 할 때 먼저 교사에게 전화해야 합니다. 그러나 학생의 정보를 얻고 교사를 통해 출석을 호출할 필요는 없으며 대신 교사가 학생의 출석을 관리하도록 허용해야 합니다. 그렇지 않으면 교장과 학생 사이에 불필요한 결합이 발생하므로 학생 수업이 변경되면 교사 수업과 교장 수업이 모두 수정되어야 합니다.

6. 복합 재사용 원칙

목적: 클래스 시스템이 커지는 것을 방지

의미: 클래스의 기능을 확장하려면 상속 대신 합성/집계를 사용하는 것이 우선입니다.

해결책: 클래스 간 관계가 "Is-A"인 경우 상속을 사용하고, 클래스 간 관계가 "Has-A"인 경우 조합을 사용합니다.

예: 예를 들어 브리지 모드에서는 추상화와 구현을 독립적으로 변경할 수 있습니다. 예를 들어 데코레이션 모드에서는 클래스에 대한 새 기능을 확장하는 데 하나의 클래스만 필요합니다. 그래픽 디스플레이 요구 사항의 경우 그래픽 Shape 클래스와 디스플레이 Paint 클래스를 사용하여 구현합니다. 각 Shape 클래스에는 그래픽 그리기 및 표시를 담당하는 Paint 클래스 포인터가 있습니다. Paint 클래스는 RedPaint 클래스와 BluePaint 클래스를 파생하여 Shape 클래스에 전달하여 다양한 색상의 그래픽 그리기를 실현하므로 그래픽 그리기 로직과 그래픽 그리기 구현을 독립적으로 변경할 수 있습니다. 어느 날에는 수요가 증가하고 모든 도면에 테두리를 추가해야 합니다. Paint 기본 클래스에서 파생된 PaintDecorator 클래스에는 Paint 개체 포인터가 있으며, Paint 그리기 메서드를 다시 작성합니다. AddedPaint 메서드에 대한 호출을 추가합니다. PaintDecorator 클래스에서 파생된 BorderPaintDecorator 클래스를 추가하고 AddedPaint 메서드를 재정의하고 테두리를 그리는 코드를 추가합니다. 이러한 방식으로 새 클래스를 추가하면 모든 원래 브러시 클래스의 기능을 확장할 수 있습니다.

7. 개방형 폐쇄 원칙

목적: 확장성을 향상하고 유지 관리를 용이하게 합니다

의미: 확장을 위해 개방하고 수정을 위해 폐쇄합니다. 즉, 시스템 확장이 권장되지만 기존 시스템 코드의 수정은 지원되지 않습니다. 즉, 소프트웨어에 새로운 요구 사항과 변경 사항이 있을 때 프레임워크 내에서 코드를 수정하는 대신 새로운 요구 사항에 맞게 소프트웨어 프레임워크를 확장하기만 하면 됩니다.

해결책: 디자인 패턴의 첫 6가지 원칙과 23가지 디자인 패턴을 잘 따르고, 열고 닫는 원리도 자연스럽게 잘 따라갑니다. 요구 사항의 변화에 ​​대해 미래 지향적이고 예측 가능하게 유지함으로써 추상화를 보다 광범위하게 적용할 수 있으며 설계된 소프트웨어 아키텍처는 상대적으로 안정적일 수 있습니다. 소프트웨어 요구사항의 변수 세부사항은 추상화에서 구현 클래스를 파생하여 확장됩니다.

첨부파일: 브리지 모드와 데코레이션 모드를 조합하여 재사용 원리를 합성하는 예제 코드

#include <iostream>

//绘制类
class Paint
{
public:
	virtual void Draw() = 0;
};

//红色绘制类
class RedPaint : public Paint
{
public:
	void Draw()
	{
		std::cout << "Color Red!" << std::endl;
	}
};

//蓝色绘制类
class BluePaint : public Paint
{
public:
	void Draw()
	{
		std::cout << "Color Blue!" << std::endl;
	}
};

//图形类,使用桥接模式,将图形绘制逻辑与绘制实现解耦
class Shape
{
public:
	Shape(Paint* pt) : m_pPt(pt)
	{	 
	}

	virtual void Show()
	{
		std::cout << "Shape Style:" << std::endl;
		m_pPt->Draw();
	}

protected:
	Paint* m_pPt;
};


//长方形类
class Rectangle : public Shape
{
public:
	Rectangle(Paint* pt) : Shape(pt)
	{
	}
};

//圆形类
class Circle : public Shape
{
public:
	Circle(Paint* pt) : Shape(pt)
	{

	}
};

//附加绘制类,使用装饰模式,对原有绘制类进行功能扩展
class PaintDecorator : public Paint
{
public:
	PaintDecorator(Paint* pt) : m_pPt(pt) { }
	
	void Draw()
	{
		m_pPt->Draw();
		AddedPaint();
	}
	virtual void AddedPaint() = 0;

protected:
	Paint* m_pPt;
};

//附加边框类,对绘制类添加边框绘制功能
class BoarderDecorator : public PaintDecorator
{
public:
	BoarderDecorator(Paint* pt) : PaintDecorator(pt)
	{
	}

	void AddedPaint()
	{
		std::cout << "With Boarder!" << std::endl;
	}
};

void main()
{
	Shape* pShape = new Circle(new BoarderDecorator(new RedPaint()));
	pShape->Show();

	return;
}
로그인 후 복사

관련 권장 사항:

JavaScript 디자인 패턴 팩토리 패턴 및 생성자 패턴_Javascript Skills

JavaScript 디자인 패턴에 대한 예비 연구_ javascript Skills

위 내용은 디자인 패턴의 7가지 원칙 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿