设计模式入门指南
想知道aclasstaghrefwiki10247d5PQ9aiOEArX4wi。html设计模式a是什么?在这篇文章中,我会解释为什么设计模式重要。我也会提供一些PHP的例子来解释什么时候什么情况下来使用设计模式。
什么是设计模式?
设计模式是针对我们日常编程问题的经过优化的可重用的方法。一种设计模式不仅仅是可以简单集成到系统中的一个类或者一个库。它是一个只能在正确的情境下使用的模板。它也不是只针对某种语言。一个好的设计模式应该可以适用于绝大多数语言中,同时也要依赖于语言的特性。最重要的是,任何设计模式如果用错地方的话,就有可能变成一把双刃剑,它可以是灾难性的而且为你造成许多问题。当然,用在合适的地方,它就是你的救世主。
有三种基本的设计模式
结构型
创造型
行为型
结构型设计模式通常处理实体之间的关系,使这些实体之间更容易协同工作。
创造性设计模式提供了实例化机制,在合适的情境下创建对象变得更容易。
行为型设计模式用于实体之间的通讯,使得这些实体之间互相交流更容易和灵活。
我们为什么要使用设计模式?
设计模式是针对程序问题按照原则仔细思考之后的解决方法。许多程序员都碰到过这些问题,并且针对这些问题对症下药。如果你遇到这些问题,为什么不使用已经被证明过的方法而要自己重新创建一个呢?
示例
让我们设想一下,你得到了一个任务,根据情况将两个不同行为的类合并到一起。这两个类大量应用于现有系统中的不同地方,这将使得移除这两个类而且改变现有的代码非常困难。为了作出这些改变,改变现有代码同样要测试改变后的代码,因为系统中可能在不同的组件中依赖这些改变,这将引入新的bug。取而代之,你可以实现一个基于策略模式和适配器模式的变种,就可以很容易的处理这种类型的情况。
classStrategyAndAdapterExampleClass{
privateclassone;
privateclasstwo;
privatecontext;
publicfunctionconstruct(context){
thisamp;gt;contextcontext;
}
publicfunctionoperation1(){
if(thisamp;gt;contextcontextforclassone){
thisamp;gt;classoneamp;gt;operation1inclassonecontext();
}else(thisamp;gt;contextcontextforclasstwo){
thisamp;gt;classtwoamp;gt;operation1inclasstwocontext();
}
}
}
很简单吧。现在,我们可以仔细了解一下策略模式。
策略模式
在上面的例子中,采用的策略是根据类初始化时context变量的值决定。如果context值为classone,将使用classone,否则使用classtwo。
聪明吧,但是我能在什么地方使用呢?
设想你现在正在设计一个可以更新或者创建新的用户记录的类。它仍然需要同样的输入(name,address,mobilenumber等等),但是,根据给定的情况,当更新或者创建时不得不采用不同的方法。现在,你可能只使用一个ifelse来完成这个。但是,要是你在一个不同的地方需要这个类咋办?在这种情况下,你将不得不一遍又一遍地重写同样的ifelse语句。在这种上下文环境中使用策略模式不是更轻松么?
classUser{
publicfunctionCreateOrUpdate(name,address,mobile,useridnull)
{
if(isnull(userid)){
itmeanstheuserdoesn’texistyet,createanewrecord
}else{
itmeanstheuseralreadyexists,justupdatebasedonthegivenuserid
}
}
}
现在,通常的策略模式包括封装你的算法在另外一个类中,但是在这种情况下,创建另外一个类可能会比较浪费。记住你并不是必须采用这种模板。在类似的情况中采用这种变化,就可以解决问题。
适配器模式
这同样可以让你改变一些从客户端类接收到的输入,使其和被适配者的功能吻合。
我能怎样使用它?
表述一个适配器类的另外一个术语是封装,表示允许你把行为封装到一个类中,并且在正确的情形下重用这些行为。一个经典的例子,当你为表创建一个领域类,你可以使用一个适配器类封装所有的方法到一个方法中,而不是调用不同的表并且一个一个的使用它们的方法。这不仅允许你重用你想使用的任何行为,如果你需要在不同的地方使用相同的行为的话,同样使你不必重写代码。
比较着两个实现,
非适配器方法
usernewUser();
useramp;gt;CreateOrUpdate(inputs);
profilenewProfile();
profileamp;gt;CreateOrUpdate(inputs);
如果我们需要在不同的地方这么做,或者甚至在不同的项目中重用这些代码,我们将不得不重新写下这些东西。
更好的
相反我们可以这样做:
accountdomainnewAccount();
accountdomainamp;gt;NewAccount(inputs);
在这种情况下,我们有一个封装类作为我们的账号(Account)类:
classAccount()
{
publicfunctionNewAccount(inputs)
{
usernewUser();
useramp;gt;CreateOrUpdate(subsetofinputs);
profilenewProfile();
profileamp;gt;CreateOrUpdate(subsetofinputs);
}
}
这样,每当你需要账户类的时候你就能使用它。此外,你也可以在领域类中封装其他类。
工厂方法模式
这个模式的主要目标是把不同类的创建过程封装到一个单独的方法中。通过为工厂方法提供正确的上下文环境,它能够返回正确的对象。
何时能使用它?
使用工厂方法模式的最佳时机是当你有各种各样的不同的独立实体的时候。比如说你有个按钮类,这个类有很多不同的变种,如图片按钮,输入按钮和Flash按钮。根据需要,你可能要创建不同的按钮这就是你能使用工厂为你创建按钮的地方。
abstractclassButton{
protectedhtml;
publicfunctiongetHtml()
{
returnthisamp;gt;html;
}
}
classImageButtonextendsButton{
protectedhtml;ThisshouldbewhateverHTMLyouwantforyourimagebasedbutton
}
classInputButtonextendsButton{
protectedhtml;ThisshouldbewhateverHTMLyouwantforyournormalbutton();
}
classFlashButtonextendsButton{
protectedhtml;ThisshouldbewhateverHTMLyouwantforyourflashbasedbutton
}
现在,我们能创建我们的工厂类:
classButtonFactory
{
publicstaticfunctioncreateButton(type)
{
baseClass‘Button’;
targetClassucfirst(type)。baseClass;
if(classexists(targetClass)amp;amp;amp;amp;issubclassof(targetClass,baseClass)){
returnnewtargetClass;
}else{
thrownewException(Thebuttontype’type’isnotrecognized。);
}
}
}
我们能像这样使用这段代码:
buttonsarray(‘image’,‘input’,‘flash’);
foreach(buttonsasb){
echoButtonFactory::createButton(b)amp;gt;getHtml()
}
输出的应该是所有的HTML按钮类型。这样,你将能够根据情况说明该创建哪个按钮并且重用这些条件。
装饰者模式
装饰者模式的目标就是扩展的功能可以被适用在一个特定的实例,而且同时可以能够创建一个不具备这个扩展功能的原始实例。装饰者模式同时允许为一个实例使用多个装饰者类,这样你就不必纠缠于为每个实例创建一个装饰者类。这个模式在继承时是可选择的,继承指的是你可以从一个父类中继承父类的功能。不同于继承在编译时添加行为,在情况允许下,装饰允许你在运行时添加一个新的行为。
我们可以根据以下几步实现装饰者模式:
1。创建一个装饰者类继承原始组件。
2。在装饰者类中,添加一个组件域。
3。在装饰者类的构造函数中初始化这个组件。
4。在装饰者类中,重新将所有的调用新组件的方法。
5。在装饰者类中,重写所有需要改变行为的组件方法。
我该何时使用?
当你拥有一个实体,这个实体仅在环境需要的时候拥有新的行为,这就是使用装饰者模式的地方。比如你有一个HTML连接元素,一个退出连接,你想根据当前的页面做一些稍微不同的事情。为了达到那个目标,我们可以使用装饰者模式。
首先,我们根据需要建立不同封装者。
1。如果在首页并且已经登入了,我们希望这个连接被
标签封装起来。
2。如果我们在一个不同的页面并且已经登入,我们希望这个连接被underline标签封装起来。
3。如果我们登入了,我们希望这个连接字体被加粗。
一旦我们建立好我们的封装类,我们可以开始编写了。
classHtmlLinks{
somemethodswhichisavailabletoallhtmllinks
}
classLogoutLinkextendsHtmlLinks{
protectedhtml;
publicfunctionconstruct(){
thisamp;gt;htmlLogout;
}
publicfunctionsetHtml(html)
{
thisamp;gt;htmlhtml;
}
publicfunctionrender()
{
echothisamp;gt;html;
}
}
classLogoutLinkH2DecoratorextendsHtmlLinks{
protectedlogoutlink;
publicfunctionconstruct(logoutlink)
{
thisamp;gt;logoutlinklogoutlink;
thisamp;gt;setHtml(
。thisamp;gt;html。
);
}
publicfunctioncall(name,args)
{
thisamp;gt;logoutlinkamp;gt;name(args〔0〕);
}
}
classLogoutLinkUnderlineDecoratorextendsHtmlLinks{
protectedlogoutlink;
publicfunctionconstruct(logoutlink)
{
thisamp;gt;logoutlinklogoutlink;
thisamp;gt;setHtml(。thisamp;gt;html。);
}
publicfunctioncall(name,args)
{
thisamp;gt;logoutlinkamp;gt;name(args〔0〕);
}
}
classLogoutLinkStrongDecoratorextendsHtmlLinks{
protectedlogoutlink;
publicfunctionconstruct(logoutlink)
{
thisamp;gt;logoutlinklogoutlink;
thisamp;gt;setHtml(。thisamp;gt;html。);
}
publicfunctioncall(name,args)
{
thisamp;gt;logoutlinkamp;gt;name(args〔0〕);
}
}
我们可以这么使用它们:
logoutlinknewLogoutLink();
if(isloggedin){
logoutlinknewLogoutLinkStrongDecorator(logoutlink);
}
if(inhomepage){
logoutlinknewLogoutLinkH2Decorator(logoutlink);
}else{
logoutlinknewLogoutLinkUnderlineDecorator(logoutlink);
}
logoutlinkamp;gt;render();
这里我们能够看到我们是如何在需要的时候结合多个装饰者类的。既然所有的装饰者类使用call方法,我们仍人可以调用原始的方法。如果我们假设我们现在在首页并且已经登入了,HTML输出应该是:
lt;h2gt;lt;stronggt;lt;ahreflogout。phpgt;Logoutaamp;gt;h2amp;gt;strongamp;gt;lt;agt;lt;stronggt;lt;h2gt;
单件模式
因为单件变量对于所有的调用都是一样的,这使得其他对象使用单件实例更简单。
我该何时使用?
如果你需要把一个特定的实例从一个类传递到另外一个类,你能够使用单件模式来避免不得不通过构造函数或者参数传递这个实例。设想你已经创建了一个会话(Session)类,模仿了SESSION全局数组。既然这个类仅需要被实例化一次,我们可以这样实现一个单件模式:
php
classSession
{
privatestaticinstance;
publicstaticfunctiongetInstance()
{
if(isnull(self::instance)){
self::instancenewself();
}
returnself::instance;
}
privatefunctionconstruct(){}
privatefunctionclone(){}
anyothersessionmethodswemightuse
}
getasessioninstance
sessionSession::getInstance();
职场礼仪之手机礼仪无论是在社交场所还是工作场合,放肆地使用手机已经成为礼仪的最大威胁之一,手机礼仪越来越受到关注。在国外,如澳大利亚电讯的各营业厅,就采取了向顾客提供手机礼节宣传册的方式,宣传手……
城南旧事读书笔记与心得分享《城南旧事》是2003年中国青年出版社出版的小说集,作者是台湾女作家林海音。全书通过作者英子童稚的双眼对童年往事的回忆,讲述了一段关于英子童年时的故事,反映了作者对童年的怀念和……
个要点教你画好紫色烟熏妆5个要点教你画好紫色烟熏妆1、尝试清理多余的眼影抹去的眼睑上多余的眼影,但不是破坏你的妆容,你可以使用一根棉签,蘸上遮瑕膏,涂于你想遮盖的地方,遮瑕膏可以瞬间扫出抹……
启封记忆人生何处不相逢。如今,我开始很认真的相信缘分。俗语说,两座山永远碰不到一起,但是两个人不知道哪一天就会相逢。还有人说,这世界太小了。离开曾经工作的乡镇好多年了,有部分关系……
女人做什么最赚钱这三个行业女人能比男人做得更好常人道,都说男人负责赚钱养家,女人负责生育和照顾家人。但那也是从前的时候,谁知直到现在还有一些直男癌仍直言不讳说自己是看不起女人的,说女人太过柔弱,手无缚鸡之力怎么能赚得到大钱……
黄石的儿女二十一。峰回路转贞子来西塞山区后自己找到了一家街道办的集体所有制纺纱厂当了一名挡车工,三班倒作业。每天很是辛苦。尤其是上夜班时,头昏沉沉的。从家里到厂里是一段黑漆漆的夜路……
我被幸福撞了一下表演系和新闻系的舞台剧演得非常成功,剑琪利用这次机会把作业完成的十分出色,一下成为校园热点人物,为他的大学生涯添了光辉的一笔。右右,这次真的要好好谢谢你。剑琪第一次向我说……
祖母的礼物爱的生命超越坍记的年岁。弗朗切斯柯彼特拉克从我有记忆的时候起,我就会叫祖母盖姬的名字。当我还是婴儿时,我嘴里吐出的第一句话是盖盖,而我骄傲的祖母确信我企图说出她的名……
生活从来都不是你看到的那样生活从来都不是你看到的那样,你从未真正地了解它,而你唯一能做的,就是疯狂地体验生活。你不曾懂过生活。当你为那仅余的丁点美好而辩解,生活给予你残酷的一击;当你对……
既然选择了远方便只顾风雨兼程壹既然选择了远方,便只顾风雨兼程。汪国真www。暖风清浅,流云翩跹,沧海桑田,再不见过往时间。当生活给你一百个哭泣的借口,你只需拿出一个微笑的理由。生活中总是……
适合发抖音的个性经典说说一、如果有人问起,你怎么变胖了,你就说忘了。不要解释,越解释越悲伤。二、你有男朋友真是太好了,这下我就只有一个情敌了!三、是不是像极了老公等你出门的时候!四、……
蓝天之下第二卷第二卷到期末了。老师希望叶尘留下来,说:平时要上课,看书的时间其实就周末。要真正做个读书人,还得把握假期啊。叶尘给家里打电话,弱弱地说了句想留在学校看书,被骂翅膀儿……
温暖的心歌以前,我只有学习上往来的朋友,她们不能和我畅谈心声,不能陪我笑,陪我伤心,陪我愁。可是,自从遇到她,留在我心里的遗憾消失了。她,高高的鼻梁,浓浓的眉毛,大大的眼睛,漂亮极……
人生没有修正带人生就像一幅面,画上了,就永远改不了。无底是直、是弯,是白、是黑,是大、是小,都会在你的记忆里流淌。在一个月明星稀的晚上,我们在家里看电视,爸爸说:儿子,下去扔垃圾!不,……
骑车的启示那年,我刚满8岁,爸爸送我了一辆自行车。它是蓝色的,我怀着迫不及待的心情,把车推到巷子里,立马骑了上去,由于锁掌握好平衡,自行车变成了我的敌人,向着垃圾筐进攻,我一时紧张……
人蚊大战夏天的一个寂静的夜晚,一只嗡嗡嗡叫的动物飞到了妈妈的前额,原来是一只讨厌的蚊子。这只蚊子正叮着妈妈的额头呢!妈妈绷着脸,斜瞟着眼,看着蚊子,她小心翼翼地抬起手臂,伸出手掌……
妈妈我想送给一个苹果我是一棵苹果树,在妈妈的身体下慢慢长大。我一点点探出头来,长出小苗,你让我接受暴雨的测试,在我快要干枯的时候,你帮我遮蔽阳光。有一天,我被人类踩,我那小苗弯弯曲曲的……
我学会了骑自行车在上一个暑假里,在爸爸的教导下,我学会了骑自行车。在暑假的时候,爸爸妈妈给我买了一辆自行车,并要求我一定要在这个暑假里学会。第一天我和爸爸很早就起床了,吃过早餐就和爸爸去……
黑信续写国王再次回到了书房,坐在椅子上,陷入了回忆三十年前父王刚刚驾崩,剩下还有他的哥哥,他和他的弟弟。他们三人手中各掌管着宫中的一支军队,展开了一番争夺。那场血战死伤无数,他与……
第一次当家生活中,有许多第一次。第一次骑车,第一次烧饭,第一次洗衣服但是第一次当家是我印象最深刻的。那天,家人们都出去有事了,就我一个人在家,我非常高兴。因为我再也不需要听家人的唠……
元宵乐农历正月十五是咱们中国的传统元宵节,在这一天,千家万户挂彩灯,吃元宵。元宵俗称汤圆,象征着团团圆圆。为了欢度佳节,学校组织各班汤圆DIY活动,这可馋坏了我们这些小吃货。终……
爱一直都在窗外,桃花盛开,风偶尔吹过,顿时下起了一阵桃花雨。我陶醉其中,思绪回到了从前小时候,总觉得父亲对我太过严厉,强迫我吃讨厌的食物,去无聊的兴趣班,一遍一遍地练字,纵然我又哭……
家乡的雪温暖了我的岁月一场漫天的大雪,一种浓浓的乡情,一段温暖的岁月。坐上去往家乡的巴士,雪透过窗子,迎风吹上我的脸,也把记忆吹回那段童年岁月。恍惚间,到站了,家乡,还是记忆中的样子,没……
一二三木头人游戏童年趣事就像是天上那数不胜数的星星,随意摘下一颗都是满满的回忆。尤其是在课堂内玩的一二三,木头人,更是让我印象深刻。在正午时分,老师故作神秘地走进教室,微笑着说:今天这堂……