企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
# 原型模式(在方法里克隆this) 用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象 用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。 应用场景: 类的资源非常多、性能和安全要求,一般和工厂方法结合使用。 1、如果创建新对象成本较大,我们可以利用已有的对象进行复制来获得。 2、如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。 3、需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。 如:游戏角色分身(war3的剑圣分身用这种模式效率高) ![](https://img.kancloud.cn/84/70/8470634b2c1b1050c03aa7e3cc1182cb_739x366.png) ``` <pre class="calibre17">``` <span class="token">//声明一个克隆自身的接口 </span> interface <span class="token4">Prototype</span> <span class="token3">{</span> <span class="token5">function</span> <span class="token4">copy</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//产品要实现克隆自身的操作 </span> class <span class="token4">Student</span> implements <span class="token4">Prototype</span> <span class="token3">{</span> <span class="token">//简单起见,这里没有使用get set </span> public $school<span class="token3">;</span> public $major<span class="token3">;</span> public $name<span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>$school<span class="token3">,</span> $major<span class="token3">,</span> $name<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>school <span class="token1">=</span> $school<span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>major <span class="token1">=</span> $major<span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>name <span class="token1">=</span> $name<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">printInfo</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token4">printf</span><span class="token3">(</span><span class="token2">"%s,%s,%sn"</span><span class="token3">,</span> $this<span class="token1">-</span><span class="token1">></span>school<span class="token3">,</span> $this<span class="token1">-</span><span class="token1">></span>major<span class="token3">,</span> $this<span class="token1">-</span><span class="token1">></span>name<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">copy</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> clone $this<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $stu1 <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Student</span><span class="token3">(</span><span class="token2">'清华大学'</span><span class="token3">,</span> <span class="token2">'计算机'</span><span class="token3">,</span> <span class="token2">'张三'</span><span class="token3">)</span><span class="token3">;</span> $stu1<span class="token1">-</span><span class="token1">></span><span class="token4">printInfo</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $stu2 <span class="token1">=</span> $stu1<span class="token1">-</span><span class="token1">></span><span class="token4">copy</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $stu2<span class="token1">-</span><span class="token1">></span>name <span class="token1">=</span> <span class="token2">'李四'</span><span class="token3">;</span> $stu2<span class="token1">-</span><span class="token1">></span><span class="token4">printInfo</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> 这里可以看到,如果类的成员变量非常多,如果由外部创建多个新对象再一个个赋值,则效率不高代码冗余也容易出错,通过原型拷贝复制自身再进行微小修改就是另一个新对象了。 ``` ```