-
什么是原型模式
-
什么时候用到原型模式
-
原型模式有那些优缺点
-
oc与java语法上原型模式有那些异同及简单的例子
-
首先看什么是原型模式:
java:Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.(用原型实例制定创建对象的种类,并且创建一个新的对象从原型对象拷贝而来。)
iOS:客户端知道抽象prototype类,在运行时,抽象Prototype子类的任何对象都可以按照客户端的意愿被复制,因此无需手工创建就可以制造同一个类型的多个实例。
根据两者定义可以看出,原型模式就是,通过复制对象来创建新的实例。核心关键就是复制。
我们看一下iOS与Java原型模式的通用类图:
Java:
iOS:
从他们的原型模式图可以看出他们有一个关键的方法:clone-克隆方法。从定义我们也不难得出原型模式就是对Prototpye对象的复制。
-
什么时候用原型模式
根据定义可以知道原型模式的核心就是clone或者copy,那为什么我们不直接new一个对象或者alloc一个对象反而要通过复制来得到对象呢?
首先比较直观的就创建起来比较麻烦,不是简单的new或者alloc。我们先看一些书上的描述:
-
需要创建的对象应独立于其类型与创建方式
-
需要实例化的类是在运行时决定的
-
不想要与产品层次相对应的工厂层次
-
不同类的实例之间差异仅是状态的若干组合,因此复制相应数量的原型比手工实例创建更方便
-
类不容易创建,比如每个组件可把其他组件作为子节点的组合对象。复制已有的组合对象对副本修改会更加容易
首先这些文字很绕口,先找比较好理解的解释,需要要实例化的类是在运行时才决定,这个什么意思呢,我的理解就是这个对象是一个组合对象,比如一个树形结构的对象,不知道他具体的实现,也没法创建,所以我copy一份。
不同实例之间差异仅是状态的组合,这个也比较好理解,比如我画一个小人头,但是我需要很多小人头他们只是颜色不一样,黄中,白种,黑中,我不必把他们都重新画一边,我只需要画出一个来,其他都复制于他,然后修改颜色就可以。
类不容易创建,这个就更好理解,我们创建一个类需要很多步骤,比如分配内存,然后加载数据,数据有来自数据库等等,所以copy更节约资源。
不想要与产品层次相对应的工厂层次 与 需要创建的对象应独立于其类型与创建方式 我的理解就是这样情况用new或者alloc会很不合适比如一个程序有很多人参与一个程序员可能只负责编写其中的一块,当你尝试编写一个完全符合DIP的系统时,你可能无法避免要创建符合特定接口的新对象,但因为DIP原则不允许你依赖具体类型,完全无法决定要创建哪一个具体类,这个时候,原型模式提供了一个很讨巧的办法:“我要创建一个跟它类型一样的对象!这个欢迎大家讨论。
-
原型模式有那些优缺点
上面的描述中基本上都是原型模式的优点,他的缺点就是每个原型类都需要实现copy方法,如果类的某个对象不支持复制,那就会遇到很多麻烦。
-
oc与java语法上原型模式有那些异同及简单的例子
首先他们都有一个关键点-复制,iOS里面有深浅复制,当然java里面也有 我们可以用一个共性的图来表示一下
大体来说就是浅拷贝只是拷贝的指针,资源没有复制,被拷贝的指针都指向同一块内存区域,*p修改任何一个都会修改资源,深拷贝就是完全两个对象,当然资源也被复制。
java中有的基类Object类中有一个clone方法,这个方法就是原型模式的关键。Java原型模式的通用源码
-
public class Niuqhclass implements Cloneable {
-
-
@Override
-
public myclass clone()
-
{
-
Niuqhclass niuqh = null;
-
try {
-
niuqh = (Niuqhclass)super.clone();
-
}
-
catch(CloneNotSupportedException e)
-
{
-
e.printStackTrace();
-
}
-
return niuqh;
-
}
iOS的实现方式则主要是要实现NSCopying,重写copyWithZone:的方法。
还是直接上例子:假如有一天易车网互联网排名世界第一了,需要在美英日三国分别成立一个公司,公司架构和现在的一样,我们来看看java和iOS的两种实现:
java:
-
package MyClass;
-
/*
-
* 易车网类
-
* 只列举了ceo和员工当然实际情况是一个树形的结构比这要复杂的多
-
* 这个实现了 接口 Cloneable 重写了 public clone()方法
-
* */
-
public class Yiche implements Cloneable {
-
-
public Yiche() {
-
}
-
ceo
-
private String ceo;
-
-
private String employee;
-
@Override
-
public Yiche clone()
-
{
-
Yiche yc = null;
-
try {
-
yc = (Yiche)super.clone();
-
}
-
catch(CloneNotSupportedException e)
-
{
-
e.printStackTrace();
-
}
-
return yc;
-
}
-
相关的set/get方法
-
public String getCeo(){
-
return ceo;
-
}
-
public void setCeo(String ceo){
-
this.ceo = ceo;
-
}
-
-
public String getEmployee()
-
{
-
return employee;
-
}
-
public void setEmployee(String employee){
-
this.employee = employee;
-
}
场景类
-
private static int MAX_COUNT =3;
-
public static void main(String[] args) {
-
int i = 0;
-
把易车模版定义出来
-
Yiche yc = new Yiche ();
-
yc.setCeo("李斌");(CEO只有一个)
-
while(i<MAX_COUNT)
-
Yiche cloneyc = yc.clone();(拷贝一个模版,添加员工)
-
yc.setEmployee("随机人");(员工有很多不一样的 人)
这样就产生了三个子公司 可以派往 美国 英国 日本,这样复制比重新编写一个树形的对象要简单的多在看iOS中的实现
首先iOS里面要先写一个接口(协议protocol)IYiche他继承了NSObject协议。这里注意NSObject类和NSObject协议的区别以及为什么苹果这么实现,这里就不再讲了。
-
#import <Foundation/Foundation.h>
-
@protocol IYiche <NSObject>
-
@property(nonatomic,retain)NSSting *ceo;
-
@property(nonatomic,retain)NSSting *employee;
-
-(id)copy;
-
@end
-
易车公司实现了协议IYiche
-
#import <Foundation/Foundation.h>
-
-
#import "IYiche.h"
-
@interface Yiche : NSObject<NSCopying,IYiche>
-
{
-
@protected
-
子公司自己的想要加的实例
-
}
-
@property(nonatomic,retain)NSSting *ceo;
-
@property(nonatomic,retain)NSSting *employee;
-
-
-(id)copyWithZone:(NSZone *)zone;
-
@end
这里会有一个问题为什么不是接口的中的copy方法而是
-(id)copyWithZone:(NSZone *)zone;方法,首先IYiche实现了NSCopying协议接口查看api在这个协议里面是没有copy方法的,这个方法在NSCopying类中,NSCopying类接受到copy消息,会想采用了NSCopying协议的子类转发消息,子类需要实现NSCopying协议中定义的-(id)copyWithZone:(NSZone *)zone;方法。NSCopying协议没有copy方法所以才才让IYiche声明了。看一下此方法的实现
#pragma mark -
#pragma mark NSCopying method
//此方法需要实现,以支持备忘录
-(id)copyWithZone:(NSZone *)zone
{
// 在这里使用self class 是希望其子类也能返回和子类一样的类型
Yiche *yichecopy = [[[self class]allocWithZone:zone]init];
return yichecopy;
}
具体的场景类就不再写了,主要是说明原型模式的简单例子,再写的时候也感觉到有一些不足,觉得能理解的东西在写的时候也感觉不那么敢确定,本文主要参考了Object-c编程之道,设计模式之蝉,COCOA设计模式。如果有理解不到位的地方希望大家提出自己的意见,给予改正。
请大家关注ios编程与大数据进行讨论: