목차
php设计模式笔记--总结篇,php设计模式--
백엔드 개발 PHP 튜토리얼 php设计模式笔记--总结篇,php设计模式--_PHP教程

php设计模式笔记--总结篇,php设计模式--_PHP教程

Jul 12, 2016 am 09:06 AM
디자인 패턴

php设计模式笔记--总结篇,php设计模式--

一、引入

   设计模式的一般定义不再说,只大概说一下我理解的设计模式,我理解的设计模式的主要目的是利用面向对象(类、接口等)特点,让代码更加易于扩展,易于重用,易于维护。这三个特点也就要求我们不要将太多功能积攒到一个类里面,而是分配到更多的类里面。所以,二十种乃至更多的设计模式主要是围绕上述四个目的进行设计的。

  php设计模式这一本书讲了19种设计模式,但其实有大部分设计模式思想上或者设计上是一样的思维与形式,我将在下面进行归类和总结,以便于大家更好地理解这本书,但大家最好看一下这本书,里面的使用的例子比较简单,看书的时候记住这本书为了代码上更简单,有些应该通过实现接口来更加规范的地方没有加接口。

  (注意:由于本文是对《php设计模式》这本书进行总结,所以时间原因书中的例子我有所提到但是并没有写在本文中,大家可以通过查看电子书,以后我也会在分别介绍各个模式的文章或者本文中补充例子)

二、创建类的时候需要考虑的模式

  面向对象最终要的概念就是类,从面向过程转换到对象,类是重要的步骤。那么创建一个类,各个类之间的依赖如何来实现,就是一个很重要的问题,下面的几个模式就是针对这一问题的。

1、建造者模式

  我们应该在代码中尽量减少new的出现,这是创建类的一个重要方式没错,但是我们应该让他尽量出现在建造者或者说工厂中,而不应该出现在一个类的方法中。原因一,可能这个类的初始化方式比较麻烦,不光需要new,还需要往其new的构造函数里面传参,那么我们首先要建立那些参数,而那些参数中可能还有对象需要new,这个初始化操作就特别长;原因二,很可能这个类以后需求可能会改变,那么初始化操作我们就需要改变,改变的操作也是在别的类里进行的,这不符合各个类之间独立的原则。

2、工厂模式--延伸的建造者模式

  当很多代码和框架中说道工厂模式的时候,其实它做的事情就是建造者模式,我认为工厂模式的意义更多的是让建造者模式更有弹性的抽象工厂。接着建造者模式的概念,如果有一些类有着一套标准得创建过程,那么我们可以先建一个抽象工程,然后各个具体类继承这个类,pizza工厂就是一个很好的例子。

3、补充:服务的概念--众多php框架的核心,依赖注入的实现方式。依赖注入比较重要,我将在别的文章里进行说明。

  如果我们看php的两大框架symfony和zend framework我们会发现有个很重要的概念叫做依赖注入(dependency injection),也就是如果解决类之间依赖的问题,实现的方式有个很重要的概念叫做 service,或者说service container。在我的理解上这和工厂模式很类似,zf中也可以将一个服务指向一个具体的工厂,而在工厂的类中我们也可以实现抽象工厂,所以说这两个是概念上类似,但是并不冲突的方式。之后会单独介绍。

三、当需求改变或增加功能时

以下模式能够方便我们重用代码

1、适配器模式

  我们说当功能变化的时候,我们应该保证类的接口不变,这样可以保证一个类变化的时候,它使用或者使用它的类的代码不需要变化。但是,毕竟会有违背这个原则的代码和类出现,比如书中所举例子,本来分解errorobject的功能应该由发生需求改变的类logtocsvadapter来实现,但是可能出于很多原因(比如代码是不可更改,不开源的),没有这么做。而适配器模式就是用来处理这种情况,他可以通过extend(比如书中的用法),也可以通过将其作为成员变量的方式,重新实现一个符合要求的接口。

2、装饰器模式

  形式:将被装饰的类作为其成员,通过成员调用方法。

  当你想为一个类添加功能却又害怕改坏了一个类的时候可以使用这种模式,但这种想法终究不能从根本上解决问题。

  另一种常用的场景是如果你只想展示给别人这个类的某一些功能而不是全部的功能。

3、中介者模式(类似事件模式)

  形式:多个有联系的类将中介者类作为其成员,调用某个方法会通过中介者来改变所有在中介者中注册的类的状态,所以注册的类需要实现一个接口供中介者调用。

     和观察者类似。

  结构上类似事件模式,只不过注册是写死(hardcode)在中介者(对应事件中的注册机)中,但是其解决问题的思路是事件的一个特例,所以叫做中介者模式。

  假设有一个类,又有一个类在概念中和第一个类是平行的(可能是一开始就有的类,也可能是随着需求的变化又出现的一个类),这两个类有联系,一个类的改变需要改变另一个类的状态,这个时候需要中介者。具体例子会在事件模式中介绍。

四、将功能分散到更多的类中

  实际项目中,维护一个有很多功能的“大”类是很麻烦的,这不符合高内聚低耦合的原则,一个类如果功能越多,那么就越面向过程,各个功能的联系越紧密,其实面向对象要解决的主要问题也是如何用更易于管理的方式将功能分布到更多的类中,听起来简单,实际上如果使用不好的方式分出来的类反而会更乱,从某种意义上这也是设计模式出现的原因。还有比如说一个人负责维护一个类,负责这个类的测试,如果结果每当一个功能发生变化他都要更改这个类的测试代码,如果我们将功能分布到更多的类中,就可以保证该类的测试代码不发生变化。

1、事件模式(会单独写一篇文章详细介绍,这里简介

  很多人包括我对事件的印象留在窗口进程中,我们单击鼠标或者按钮会有一个事件,它会改变所有注册了该事件的对象,可能是视图发生变化,也可能是我们自己定义的一个函数,中介者模式也类似事件模式,只不过是所有在中介者中注册的都是平等的关系,比如一个表格和一个柱状图,我们改变表格的内容会引起柱状图的改变,我们缩短加长柱状图会改变表格的内容。但是在一般的应用逻辑中事件模式和中介者模式有什么用?

  我们要抛开上面所说的事件的意义,上面只是事件的一个特例,这里说明一下事件更一般的用法。其实事件本质上是中介者模式,中介者是把注册的容器放在了需要被改变的类中,相当于事件中传入event中的对象,但有些类在一开始并没有设计成中介者模式,也就是说类中没有保存一个中介者的成员,可能是因为没想到这个需求,也可能是因为觉得在类中加入这个机制比较麻烦,而是选择了可以在类外实现相同功能的事件模式。(所以说中介者模式是可以转换成事件模式的,虽然事件模式免去了在类内的麻烦,但是却需要提供一套事件的机制,相对于中介者在类外更加麻烦的,但由于分离到类外,所以有很多现成的中介者实现,比如各个框架基本都实现了这一机制,symfony更是可以将这一组件用在不是symfony的框架中。

  在除了上面视图界面的操作中,别的例子可能不是那么直观,不那么符合事件这个名字,它的主要作用就像大标题中所写的那样,是通过事件模式的代码结构来更好的分割代码的功能使其更易管理。所以要理解就要忘记事件的一般含义。思考一个逻辑比较复杂的例子,一个电话公司,会针对用户的通话记录计算其花费,众所周知这是一套很复杂的逻辑,根据用户的不同套餐和使用地区都会有差别,那么那么一长串逻辑判断代码我们难道要写在一个类中么?肯定不符合我们的原则,那么我们就利用事件模式的形式(反复强调只是形式),来实现将逻辑分到不同的类中。我们把所有的电话服务都作为listener,进行注册,每一条通话记录作为subscriber,都通过if语句来判断属于哪一个业务,然后对向那些业务dispatch,listener获取账单对象,对其进行更改,最后的账单对象就是最终的账单信息。通过事件模型,我们将不同的处理逻辑分出来成为listener对象,更方便以后的扩展。

  上面的例子是通过listener修改对象,也可以仅仅是利用获得对象信息进行相关操作,比如博客园发布一篇博文会有很多的操作,比如需要存数据库,需要进行倒排操作,需要进行标签操作,如果要发布到首页也需要另外的额一系列操作,可以通过一些listener来监听发布博文这一个操作,本身并没有修改Post这个对象,而是利用Post对象信息进行操作。

  回到更一般的说法,事件模式主要应用在插件(plugin),当然是更广义的插件。这是symfony的介绍Consider the real-world example where you want to provide a plugin system for your project. A plugin should be able to add methods, or do something before or after a method is executed, without interfering with other plugins. This is not an easy problem to solve with single and multiple inheritance (were it possible with PHP) has its own drawbacks.

  从上面的意义上讲,事件是以一种更利于扩展的方式处理和加工对象的机制,在你想利用这个机制的时候都可以用事件,并且借助现有框架中的事件组件,你可以将观察者和中介者都转化为事件模式,所以事件其实很常用,在c#中事件的重视中也可以体现。

  也可以看一下symfony事件文档来学习一下事件的运用。

2、观察者模式

  形式:$this->obserber->update($this),而中介者的形式是$this->mediator->chage($this,array('band'=>$newname))。可以看出来只不过是为了完成两种不同的功能需求。而这两者都可以通过事件来代替,前者发送一个update事件,后者发送一个changeBandName事件,然后通过查看传入对象的name来实现change。

3、委托模式

  通过分配或者委托至其他对象,委托设计模式能够去除核心对象中判决(if语句)复杂的功能性。和c#中委托的概念相似,c#中是用函数的形式,将委托作为参数传到别的函数中,从而将功能性分到别的方程。面向对象里的委托是把功能性分到委托类中。

  形式:被委托类中有一个委托类的成员变量。

4、策略模式

  在能够创建应用于基于对象的、由自包含算法组成的可互换对象时,最佳做法是使用策略模式。

  和委托模式基本一致,无论是形式还是意义上,只不过书中的例子委托模式是把$this->playlist传递给了委托模式,但是策略模式把整个$this都传给了策略模式。

  策略模式还有一个重要的意义,如果一个类的某个方法不经常用,可以转换成策略模式,这样就不必在类的测试中每次都要测试这个类了。

 

5、代理模式

  代理模式可以有不同的形式,只要是被赋予了“代理”这个意义。书中通过装饰器的继承形式实现了代理。

五、其他

以下都是很常见的模式

1、面向对象与生俱来的模式--模板模式

  就不详细介绍了,和抽象类和接口是一个思想。

2、外观模式(facade)

  facade这个单词在一些框架中类的命名中很常见,类似面向过程中function的作用,把一系列针对某个特定功能的代码封装到一个类中一个static方法中,通常该类也只有这一个方法。

3、公共方法抽象成类--数据访问对象模式

  公共方法抽象成类是面向对象的基本原则,不仅是一个实体,如果是一个功能可以被多个实体或者功能所使用,那么我们应该为他单独成类,其他类如果使用它那也就是上文所说的依赖注入(dependency injection)。

  数据访问对象模式也是这一模式的基本实践。可以结合zend famework的guide http://framework.zend.com/manual/current/en/in-depth-guide/preparing-db-backend.html 进行理解。基本上是为了封装数据的操作,tablegateway也是这一领域的成熟的模式,基本上是一个表一个类,但这样也就限制了数据库本身的连接操作,我们只能通过类之间的操作来实现连接,具体我会在其他文章中写。

4、系统中只需要一个-单元素模式

  这个模式也很常见

六、书中关键句子笔记

1、不同对象的连接才是简化的目标

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1065784.htmlTechArticlephp设计模式笔记--总结篇,php设计模式-- 一、引入 设计模式的一般定义不再说,只大概说一下我理解的设计模式,我理解的设计模式的主要...
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

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

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

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

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Java 프레임워크의 디자인 패턴과 아키텍처 패턴의 차이점 Java 프레임워크의 디자인 패턴과 아키텍처 패턴의 차이점 Jun 02, 2024 pm 12:59 PM

Java 프레임워크에서 디자인 패턴과 아키텍처 패턴의 차이점은 디자인 패턴이 클래스와 객체(예: 팩토리 패턴) 간의 상호 작용에 중점을 두고 소프트웨어 디자인의 일반적인 문제에 대한 추상적인 솔루션을 정의한다는 것입니다. 아키텍처 패턴은 계층화된 아키텍처와 같은 시스템 구성 요소의 구성 및 상호 작용에 중점을 두고 시스템 구조와 모듈 간의 관계를 정의합니다.

Java 디자인 패턴에서 어댑터 패턴의 놀라운 사용 Java 디자인 패턴에서 어댑터 패턴의 놀라운 사용 May 09, 2024 pm 12:54 PM

어댑터 패턴은 호환되지 않는 개체가 함께 작동할 수 있도록 하는 구조적 디자인 패턴입니다. 이는 개체가 원활하게 상호 작용할 수 있도록 하나의 인터페이스를 다른 인터페이스로 변환합니다. 개체 어댑터는 적응된 개체를 포함하는 어댑터 개체를 만들고 대상 인터페이스를 구현하여 어댑터 패턴을 구현합니다. 실제적인 경우 클라이언트(예: MediaPlayer)는 어댑터 모드를 통해 고급 형식 미디어(예: VLC)를 재생할 수 있지만 클라이언트 자체는 일반 미디어 형식(예: MP3)만 지원합니다.

Java 디자인 패턴의 데코레이터 패턴 분석 Java 디자인 패턴의 데코레이터 패턴 분석 May 09, 2024 pm 03:12 PM

데코레이터 패턴은 원래 클래스를 수정하지 않고도 객체 기능을 동적으로 추가할 수 있는 구조적 디자인 패턴입니다. 추상 컴포넌트, 콘크리트 컴포넌트, 추상 데코레이터, 콘크리트 데코레이터의 협업을 통해 구현되며, 변화하는 요구에 맞게 클래스 기능을 유연하게 확장할 수 있습니다. 이 예에서는 우유와 모카 데코레이터가 총 $2.29의 가격으로 Espresso에 추가되어 객체의 동작을 동적으로 수정하는 데코레이터 패턴의 힘을 보여줍니다.

PHP 디자인 패턴 실제 사례 분석 PHP 디자인 패턴 실제 사례 분석 May 08, 2024 am 08:09 AM

1. 팩토리 패턴: 객체 생성과 비즈니스 로직을 분리하고, 팩토리 클래스를 통해 지정된 형태의 객체를 생성합니다. 2. 관찰자 패턴: 주체 개체가 관찰자 개체에 상태 변경을 알리도록 허용하여 느슨한 결합 및 관찰자 패턴을 달성합니다.

Java 프레임워크에서 디자인 패턴을 사용할 때의 장점과 단점은 무엇입니까? Java 프레임워크에서 디자인 패턴을 사용할 때의 장점과 단점은 무엇입니까? Jun 01, 2024 pm 02:13 PM

Java 프레임워크에서 디자인 패턴을 사용하면 향상된 코드 가독성, 유지 관리성 및 확장성이 향상된다는 이점이 있습니다. 단점으로는 복잡성, 성능 오버헤드, 과도한 사용으로 인한 가파른 학습 곡선 등이 있습니다. 실제 사례: 프록시 모드는 개체를 지연 로드하는 데 사용됩니다. 디자인 패턴을 현명하게 사용하여 장점을 활용하고 단점을 최소화하세요.

디자인 패턴이 코드 유지 관리 문제를 처리하는 방법 디자인 패턴이 코드 유지 관리 문제를 처리하는 방법 May 09, 2024 pm 12:45 PM

디자인 패턴은 재사용 및 확장 가능한 솔루션을 제공하여 코드 유지 관리 문제를 해결합니다. 관찰자 패턴: 개체가 이벤트를 구독하고 이벤트가 발생할 때 알림을 받을 수 있도록 합니다. 팩토리 패턴: 구체적인 클래스에 의존하지 않고 객체를 생성하는 중앙 집중식 방법을 제공합니다. 싱글톤 패턴: 클래스에 전역적으로 액세스 가능한 개체를 만드는 데 사용되는 인스턴스가 하나만 있는지 확인합니다.

Guice 프레임워크에 디자인 패턴 적용 Guice 프레임워크에 디자인 패턴 적용 Jun 02, 2024 pm 10:49 PM

Guice 프레임워크는 다음을 포함한 다양한 디자인 패턴을 적용합니다. 싱글톤 패턴: @Singleton 주석을 통해 클래스에 인스턴스가 하나만 있는지 확인합니다. 팩토리 메소드 패턴: @Provides 주석을 통해 팩토리 메소드를 생성하고 종속성 주입 중에 객체 인스턴스를 얻습니다. 전략 모드: 알고리즘을 다양한 전략 클래스로 캡슐화하고 @Named 주석을 통해 특정 전략을 지정합니다.

PHP 디자인 패턴: 실제 테스트 중심 개발 PHP 디자인 패턴: 실제 테스트 중심 개발 Jun 03, 2024 pm 02:14 PM

TDD는 고품질 PHP 코드를 작성하는 데 사용됩니다. 단계에는 테스트 사례 작성, 예상 기능 설명 및 실패 만들기가 포함됩니다. 과도한 최적화나 세부 설계 없이 테스트 케이스만 통과하도록 코드를 작성합니다. 테스트 케이스를 통과한 후 코드를 최적화하고 리팩터링하여 가독성, 유지 관리성 및 확장성을 향상시킵니다.

See all articles