一、什么是结构型模式?
结构型模式是解析类和对象的内部结构和外部组合,通过优化程序结构解决模块之间的耦合问题。
二、结构型模式的种类:
适配器模式
桥接模式
装饰模式
组合模式
外观模式
享元模式
代理模式
1、 适配器模式(Adapter)
将一个类的接口转换成客户希望的另一个接口,适配器模式使得原本的由于接口不兼容而不能一起工作的那些类可以一起工作。
应用场景:老代码接口不适应新的接口需求,或者代码很多很乱不便于继续修改,或者使用第三方类库。
代码实现
- /**
- * 适配器模式
- */
- //老的代码
- class User {
- private $name;
- function __construct($name) {
- $this->name = $name;
- }
- public function getName() {
- return $this->name;
- }
- }
- //新代码,开放平台标准接口
- interface UserInterface {
- function getUserName();
- }
- class UserInfo implements UserInterface {
- protected $user;
- function __construct($user) {
- $this->user = $user;
- }
- public function getUserName() {
- return $this->user->getName();
- }
- }
- $olduser = new User('张三');
- echo $olduser->getName()."n";
- $newuser = new UserInfo($olduser);
- echo $newuser->getUserName()."n";
复制代码
注意点:这里的新接口使用了组合方式,UserInfo内部有一个成员变量保存老接口User对象,模块之间是松耦合的,这种结构其实就是组合模式。不要使用继承,虽然UserInfo继承User也能达到同样的目的,但是耦合度高,相互产生影响。
2、 桥接模式
将抽象部分与它的实现部分分离,使它们都可以独立变化
特点:独立存在,扩展性强
应用:需要不断更换调用对象却执行相同的调用方法,实现扩展功能
代码实现
- /**
- *
- * 桥接模式
- *
- */
- abstract class Person {
- abstract function getJob();
- }
- class Student extends Person {
- public function getJob() {
- return '学生';
- }
- }
- class Teacher extends Person {
- public function getJob() {
- return '老师';
- }
- }
- class BridgeObj {
- protected $_person;
- public function setPerson($person) {
- $this->_person = $person;
- }
- public function getJob() {
- return $this->_person->getJob();
- }
- }
- $obj = new BridgeObj();
- $obj->setPerson(new Student());
- printf("本次桥接对象:%sn", $obj->getJob());
- $obj->setPerson(new Teacher());
- printf("本次桥接对象:%sn", $obj->getJob());
复制代码
3、 装饰模式
动态地给一个对象添加额外的职责。在原有的基础上进行功能增强。
特点:用来增强原有对象功能,依附于原有对象。
应用:用于需要对原有对象增加功能而不是完全覆盖的时候
代码实现
- /**
- *
- * 装饰模式
- *
- */
- //产品
- abstract class Person {
- abstract function getPermission();
- }
- //被装饰者
- class User extends Person {
- public function getPermission() {
- return '公开文档';
- }
- }
- //装饰类
- class PermUser extends Person {
- protected $_user;
- protected $_special = '';
- function __construct($user) {
- $this->_user = $user;
- }
- public function getPermission() {
- return $this->_user->getPermission() . $this->_special;
- }
- }
- //装饰类产品
- class JavaUser extends PermUser {
- protected $_special = ' java程序';
- }
- class CPlusUser extends PermUser {
- protected $_special = ' c++程序';
- }
- $user = new User();
- printf("permission:%sn", $user->getPermission());
- $user = new JavaUser($user);
- printf("permission:%sn", $user->getPermission());
- $user = new CPlusUser($user);
- printf("permission:%sn", $user->getPermission());
复制代码
大家想想装饰和继承的区别在哪?
如果是上面的例子,如果用继承,是CPlusUser继承JavaUser还是反过来呢?谁也不知道最终使用者需要哪一种。
在多层关系的情况下,装饰是和顺序无关并且随时增加装饰,而继承只能是特定的顺序,所以装饰模式会更加的灵活。
4、组合模式
将对象组合成树形结构表示“部分-整体”的层次结构。
特点:灵活性强
应用:对象的部分-整体的层次结构,模糊组合对象和简单对象处理问题
代码实现
- /**
- * 组合模式
- *
- */
- //继承模式
- class UserBaseInfo {
- private $name;
- function __construct($name) {
- $this->name = $name;
- }
- public function getName() {
- return $this->name;
- }
- }
- class User extends UserBaseInfo {
- private $login = false;
- public function setLogin($islogin) {
- $this->login = $islogin;
- }
- public function isLogin() {
- return $this->login;
- }
- }
- $user = new User('张三');
- $user->setLogin(true);
- if ($user->isLogin()) {
- echo $user->getName()."已经登录了n";
- } else {
- echo $user->getName()."还没有登录n";
- }
- //组合模式
- class LoginInfo {
- protected $user;
- protected $login = false;
- public function setLogin($user, $isLogin) {
- $this->user = $user;
- $this->login = $isLogin;
- }
- public function isLogin() {
- return $this->login;
- }
- }
- $user = new User('张三');
- $login = new LoginInfo();
- $login->setLogin($user, true);
- if ($login->isLogin()) {
- echo $user->getName()."已经登录了n";
- } else {
- echo $user->getName()."还没有登录n";
- }
- //部分可以更换,用继承则不行
- class Admin {
- protected $level;
- function __construct($level) {
- $this->level = $level;
- }
- function getLevel() {
- return $this->level;
- }
- }
- $admin = new Admin(1);
- $login->setLogin($admin, true);
- if ($login->isLogin()) {
- printf("级别为 %d 的管理员已经登录了n", $admin->getLevel());
- } else {
- printf("级别为 %d 的管理员还没有登录n", $admin->getLevel());
- }
复制代码
上面的例子分别展示了使用继承和组合来处理新功能,在简单的情况下看似区别不大,但在项目后期越来越复杂的时候组合模式的优势就越来越明显了。
例如上面的登录信息,如果要增加登录次数、最后登录时间、登录ip等信息,登录本身就会变成一个比较复杂的对象。如果以后有新的需求比如好友信息、用户的访问信息等,再要继承的话,用户类就会变得非常庞大,难免各父类之间没有冲突的变量和方法,而外部访问用户类的众多方法也变得很费劲。采用组合模式后,一个类负责一个角色,功能区分非常明显,扩展方便。
5、 外观模式(门面模式)
为了系统中的一组接口提供一个一致的界面
特点:向上抽取,有共性
应用:内部接口众多,由统一的接口来调用
代码实现
- class Operation {
- public function testPlus() {
- printf("plus: %sn", (1 + 2 == 3 ? 'true' : 'false'));
- }
- public function testMinus() {
- printf("minus: %sn", (3 - 2 == 2 ? 'true' : 'false'));
- }
- public function testTimes() {
- printf("times: %sn", (2 * 3 == 6 ? 'true' : 'false'));
- }
- }
- class Tester {
- protected $_operation;
- function __construct() {
- $this->_operation = new Operation();
- }
- public function testAll() {
- $this->_operation->testPlus();
- $this->_operation->testMinus();
- $this->_operation->testTimes();
- }
- }
- //测试用例,测试全部接口
- $tester = new Tester();
- $tester->testAll();
复制代码
门面模式估计大家在实际代码中都已经使用到了,接口较多时把相似功能的接口封装成一个接口供外部调用,这就是门面模式。
6、 享元模式
运用共享技术有效地支持大量细粒度对象,采用一个共享来避免大量有相同内容对象的开销。这种开销中最直观的就是内存的损耗。
特点:高效性,共享性
应用:系统底层的设计。例如字符串的创建。如果两个字符串相同,则不会创建第二个字符串,而是第二个的引用直接指向第一个字符串。$str1=”abc”,$str2=”abc”.则内存存储中只会创建一个字符串“abc”而引用$str1.$str2都会指向它。
7、 代理模式
为其他对象提供一个代理来控制对这个对象的访问,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用。能够协调调用者和被调用者,能够在一定程度上降低系统的耦合性。
特点:低耦合性,独立性好,安全性
应用:客户访问不到或者被访问者希望隐藏自己,所以通过代理来访问自己。
代码实现
- //内部对象
- class User {
- public function getName() {
- return '张三';
- }
- public function getType() {
- return '付费用户';
- }
- }
- //代理接口定义,例如开放平台
- interface UserInterface {
- function getName();
- }
- //代理对象
- class UserProxy implements UserInterface {
- protected $_user;
- function __construct() {
- $this->_user = new User();
- }
- public function getName() {
- return $this->_user->getName();
- }
- }
- //内部调用
- $user = new User();
- printf("user name:%sn", $user->getName());
- printf("user type:%sn", $user->getType());
- //外部调用
- // $user = new UserProxy();
- // printf("user name:%sn", $user->getName());
- // printf("user type:%sn", $user->getType()); //不能访问,及时知道内部对象有这个方法
复制代码
三、总结
1、代理模式、适配器模式、门面模式、装饰模式的区别
a、 相同之处:都封装一个内部对象,调用内部对象的方法
b、 不同之处:各自有各自的特性和应用场景,不能相互替代。所以用的时候要仔细分析用那种合适。
2、 关于模式的选用问题
模式的选用要根据实际的业务需求,通过对业务逻辑的仔细分析,再根据模式具有的特性和应用场景进行合理的选择和区分。大部分情况下业务的场景决定了哪种模式,而不是选择哪个模式去实现一个业务,少数情况几种模式确实都能解决问题,那主要就是考虑以后的扩展了。
到这里我们已经了解了7种结构型模式,下一篇我们继续给大家介绍设计模式的行为型模式,先预览一下行为型模式的种类吧:
u 模版方法模式
u 命令模式
u 迭代器模式
u 观察者模式
u 终结者模式
u 备忘录模式
u 解释器模式
u 状态模式
u 策略模式
u 职责链模式
u 访问者模式

PHP 로깅은 웹 애플리케이션을 모니터링하고 디버깅하고 중요한 이벤트, 오류 및 런타임 동작을 캡처하는 데 필수적입니다. 시스템 성능에 대한 귀중한 통찰력을 제공하고 문제를 식별하며 더 빠른 문제 해결을 지원합니다.

Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> 'Hello World', 'github.com'=> [ 'foo'=> 'bar'], 'forge.laravel.com'=>

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

Alipay PHP ...

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

이 기사에서는 프레임 워크에 사용자 정의 기능 추가, 아키텍처 이해, 확장 지점 식별 및 통합 및 디버깅을위한 모범 사례에 중점을 둡니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

뜨거운 주제



