1、模式标准
模式名称:原型模式
模式分类:创建型
模式意图:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象
结构图:
适用于:
1、当一个系统应该独立于它的产品创建、构成和表示时
2、当要实例化的类是在运行时刻指定时,例如,通过动态装载
3、为了避免创建一个与产品类层次平行的工厂类层次时。
4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们,可能比每次用合适的状态手工实例化该类更方便一些。
2、分析与设计
我们的unitItem经过几种模式的改造,已经变得复杂起来,通过cocos creator 中的instantiate可以克隆指定任何类型的对象,但是直接用有2个缺点不符合我们的设计。第一个是因为在unitItem中我们用亨元模式使用了fighter。如果直接用instantiate一个新对象是他拥有的是一个新fighter,并没有共享内存。第二个是因为我们的游戏框架给每个unitItem都设置了个unitId。所以我们还需要原型模式来通过这个clone操作来优化上面2个问题,当然目前大部分工作也还是instantiate完成的。
另外目前抽象工厂方法 xhgame.itemFactory.createUnitItem('abc')创建的单位是一个原胚单位,一些属性需要后期set。通过clone方法可以方便很多。
意图:用原型实例指定创建对象的种类,并且通过复制(clone)创建新的对象
3、开始打造
item
export interface IItem {
itemNo: string
reset(): void
clone(): any
}
单位的克隆
export class UnitItem extends Component implements IItem, IUnitItem {
ad: number = 100;
mp: number = 0;
// 攻击方式
fighter: Fighter;
private currentState: IUnitState = null;
clone(): UnitItem<T> {
// 克隆节点
let cloneNode = instantiate(this.node);
let clonedItem = cloneNode.getComponent(UnitItem)
clonedItem.ad = this.ad;
clonedItem.mp = this.mp;
clonedItem.setFighter(xhgame.flyweightFactory.getFighter('jinchen_futou'))
clonedItem.unitId = xhgame.itemFactory.getUnitItemId()
return clonedItem;
}
.....
}
4、开始使用
let unitItem = xhgame.itemFactory.createUnitItem('kuloubing')
unitItem.setFighter(xhgame.flyweightFactory.getFighter('jinchen_futou'));
let unitItem2 = unitItem.clone()
console.log('是否内存共享Fighter', unitItem.fighter === unitItem2.fighter) // 显示true