摘要:原型模式平行的继承层次使用工厂模式在大型设计中,必须去维护大量的产品类。上文中,称之为特殊的耦合在这里我们介绍一种其抽象工厂模式的变体原型模式。面向对象设计模式目录
原型模式
平行的继承层次使用工厂模式在:大型设计中,必须去维护大量的产品类。(上文中,称之为“特殊的耦合”)
在这里我们介绍一种其抽象工厂模式的变体:原型模式。它使用clone关键词,来复制具体产品类,使得具体产品类能完成自我复制。
(通俗介绍:工场只负责生产产品,选择生产何等产品,不再由工场自己决定,而是通过传参,来确认——对比抽象工厂,你可以发现,我们再也找不到一大群具体产品的创建者,而只有一个高度灵活的创建者)
问题假设我们在做一款类似文明(Cicilization)的网页游戏——这么经典的游戏都没玩过?成何体统[滑稽]。(屠龙宝刀,点击就送!)
里面有个 战斗用途的地理系统——三种地形:海洋 Sea/平原 Forest/森林 Plains,按照抽象工厂 + 工厂模式,我们肯定可以得到这样的结果:
(为何我的眼里常含泪水,因为StartUML2.5难用的深沉)
但我们要避免“大型的继承体系”——开头说了,这会造成另类耦合,于是,来看看原型模式的解决方法吧!
实现class Sea {} class EarthSea extends Sea {} class MarsSea extends Sea {} class Plains {} class EarthPlains extends Plains {} class MarsPlains extends Plains {} class Forest {} class EarthForest extends Forest {} class MarsForest extends Forest {} class TerrainFactory { private $sea; private $plains; private $forest; function __construct( Sea $sea, Plains $plains, Forest $forest ) { $this->sea = $sea; $this->plains = $plains; $this->forest = $forest; } function getSea() { return clone $this->sea; } function getPlains() { return clone $this->plains; } function getForest() { return clone $this->forest; } } $factory = new TerrainFactory( new EarthSea(), new EarthPlains(), new EarthForest() ); print_r( $factory->getSea() ); print_r( $factory->getPlains() ); print_r( $factory->getForest() );
读完代码,你就能看懂原型模式,创造者可以无脑的生产出一片“具备三种地形的战斗区域”,你在地球风格的海洋和森林。火星风格的平原上战斗?那么只需要传递三个对应参数即可,换而言之——创造者不再负责:我要造什么。
我们还可以增加一些灵活性,譬如:海洋地形中的航行难度——营造出一种“索马里海域 / 渤海海域”的差异(在古代,索马里海域的航船条件相当凶恶)。
class Sea { private $navigability = 0; function __construct( $navigability ) { $this->navigability = $navigability; } } ...省略部分代码... $factory = new TerrainFactory( new EarthSea( -1 ), new EarthPlains(), new EarthForest() );
可以预见,这是多么具备灵活性的模式。额外提及:如果产品类包含了其他外部类,记得采用__clone()方法,这样可以保证你得到的是深度复制(deep copy)
模式的诱导性本节没有结论(或者,这个模式很好理解),这里提及一个模式的诱导和骗术:它们并没有帮你决定Create Who?
无论是工厂模式、抽象工厂模式,亦或是原型模式,它们都只是在技术层面简化了类的数量、维护复杂度。
你还是需要自己决定:生产特定的产品——你会将这些决定留在整个代码系统,在你需要修改一处时,造成瘫痪。
解决方案:操控单例类 / 存储于数据库 / 甚至直接写到配置文件(.htaccess等)——包含大量的标记/硬编码;
个人推荐:单例类 + 配置文件,优点:方便修改、全局访问。
(面向对象设计模式 - 目录)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/22674.html
摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...
摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...
摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...
摘要:系列目录生成对象的模式面向对象的之模式单例面向对象的之模式工厂方法面向对象的之模式抽象工厂方法面向对象的之模式原型组合类对象的模式面向对象的之模式组合更新装饰模式 系列目录 生成对象的模式 【面向对象的PHP】之模式:单例 【面向对象的PHP】之模式:工厂方法 【面向对象的PHP】之模式:抽象工厂方法 【面向对象的PHP】之模式:原型 组合类/对象的模式 【面向对象的PHP】之模式...
摘要:所以,也要慎用当你的项目中,产品越来越多,创建者的数量也随之臃肿,下一篇将介绍抽象工厂方法的变体原型模式,这种模式可以减少必须创建的类。 抽象工厂方法模式 在工厂方法模式中,我们通过中间件的方式,形成了以下格式的分离: 使用者 ↓创建者 ↓具体产品 问题 这样,我们无论怎样修正具体产品,都不会影响使用者。现在,我们可以做出来一群小工厂,他们有各自的产品,但形成了模式层面的重复,那么...
阅读 3041·2021-11-23 09:51
阅读 1021·2021-09-02 15:21
阅读 2986·2019-08-30 13:56
阅读 1808·2019-08-29 14:12
阅读 685·2019-08-29 13:53
阅读 1627·2019-08-29 11:32
阅读 1281·2019-08-29 11:25
阅读 1472·2019-08-28 17:51