Python应用,DDD领域设计,Service Mesh以及自动化测试基于iOS的设计模式

原型模式

2021-09-02  本文已影响0人  helinyu

生活中的例子: 印刷术【刻画】、简历、模具

QR:创建一个对象过程过大、过于复杂? eg: 树结构
AN :重建对象并做轻微改动。eg:复制组合结构。
拷贝(浅拷贝、深拷贝) —— 原型模式

定义:用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象
扩展描述:其实就是从一个对象再创建另一个可定制的对象,而不需要任何创建的细节。
好处:一般在初始化的信息不发生变化的情况下,克隆是最好的方法。 这既隐藏了对象呢创建的细节,又对性能是大大的提高。

原型模式类型

问题: 如果里面的属性是值类型的,clone直接就拷贝出来了,如果是对象类型,则会复制引用,而不复制对象。 —— 原始对象和复制的对象引用是同一个对象。 —————— 【深拷贝和浅拷贝的问题】

//OC 实现一个简单的例子验证一下
// student 没有实现对应的copy, person实现对应的copy
@interface XNStudent : NSObject
@property (nonatomic, copy) NSString *name;
@end

@interface XNPerson : NSObject<NSCopying>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, strong) XNStudent *student;
@end

- (id)copyWithZone:(NSZone *)zone {
    XNPerson *cpy = [XNPerson allocWithZone:zone];
    if (cpy) {
        cpy.name = self.name;
        cpy.age = self.age;
        cpy.student = self.student;
//         cpy.student = [self.student copy]; 如果这样修改,将会出现错误。 应该在student里面实现这个copying协议
    }
    return cpy;
}
上面代码结果

深拷贝: 注意拷贝对象和资源本身,而不只是指针。

进行修改

//<NSCopying> 实现这个协议,  
// 实现下面的方法
- (id)copyWithZone:(NSZone *)zone {
    XNStudent *cpy = [[self class] allocWithZone:zone];
    if (cpy) {
        cpy.name = self.name;
    }
    return cpy;
}

修改之后的结果

PS: 上面可以卡卡拿到
在OC里面,如果没有实现NSCopying协议里面的copywithzone: 方法,copy出来的对象是浅拷贝,如果实现了,就是深拷贝。

QR:什么时候使用原型模式?
AN:
1)需要创建的对象应独立于其他类型与创建方式 【特殊性】
2)要实例化的类是在运行时决定的。
3)不想要与产品层次相对应的工厂层次。 【???】
4)不同类的实例间的差异仅仅是状态的若干组合。 因此赋值响应数量的原型比手工实例化更加方便。 对象间差异较小
5)类不容易创建, eg: 每个组件可把其他组件作为子节点的组合对象。 复制已有的组合对象并对副本进行修改更加容易。

PS:
1、对象间差异小
2、参数较多【操作不易】
3、对象结构复杂【不容易创建】
4、需要的对象的特殊性【独立性】
5、性能上的优化【eg:CPU操作少,内存已经知道大小,不用再去算了】

常常使用次模式的场景

  1. 有很多相关的类,其行为略有不同。
  2. 需要使用组合(树型)对象作为其他东西的基础。 eg: 使用组合对象作为组件来构建另一个组合对象。

《iOS设计模式中的绘图例子》
vertex , dot, stroke 这人几个都是遵循同样的一个接口。 里面有关的属性,我们可以声明对应的动态以及实现的关系。 来处理这个有没有实现对应的属性。【这个是一个很好的实现方式】

// vertex拷贝
- (id)copyWithZone:(NSZone *)zone;
{
    return [[[self class] allocWithZone:zone] initWithLocation:self.location];
}

// dot拷贝
- (id)copyWithZone:(NSZone *)zone {
    Dot *copy = [[[self class] allocWithZone:zone] initWithLocation:self.location];
//     复制颜色, 相当于重新创建一个颜色对象
    [copy setColor:[UIColor colorWithCGColor:[self.color CGColor]]];
    
    copy.size = self.size;
    return copy;
}

// stroke的拷贝
- (id)copyWithZone:(NSZone *)zone {
    Stroke *copy = [[[self class] allocWithZone:zone] init];
    copy.color = [UIColor colorWithCGColor:self.color.CGColor];
    copy.size = self.size;
    for (id<Mark> child in self.children) {
        id<Mark> childCopy = [child copy];
        [copy addMark:childCopy];
    }
    return copy;
}

这里的使用场景是:我们需要保存一份当时的状态【快照】。 所以,需要拷贝一份数据进行保存。


参考博客
参考0x00

上一篇 下一篇

猜你喜欢

热点阅读