原型模式定义
1.用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
克隆(浅度克隆->拷贝值类型或引用 、深度克隆->开辟一块新内存,创建对象)
原型模式应用场景
场景一:当我们编写组件需要创建新的实例对象,但是又不想依赖类的初始化构造器的时候可以采用原型模式来设计
场景二:类的初始化过程中需要消耗非常多的资源(数据、硬件资源等)可以采用原型模式。
原型模式角色划分
两个核心角色?
角色一:克隆接口
角色二:具体实现类
原型模式原理案例
数据库框架涉及到原型模式(克隆模式)
深拷贝和浅拷贝参考地址:https://www.cnblogs.com/beckwang0912/p/7212075.html
-
案例一:浅度拷贝->浅度克隆
适用于值类型(基本数据类型int/float/double...结构体)
角色一:克隆接口cloneable
// 克隆接口
// CloneableProtocol.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Foundation
protocol CloneableProtocol {
associatedtype ObjType
func clone() -> ObjType
}
角色二:具体实现
//
// ExcelDocument.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class ExcelDocument: CloneableProtocol {
var name:String
var content:String
init(name:String, content:String) {
self.name = name
self.content = content
}
func clone() -> ExcelDocument {
return ExcelDocument(name: self.name, content: self.content)
}
}
调用
//
// main.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Foundation
let excel = ExcelDocument(name: "NSLog", content: "NSError")
let clone = excel.clone()
//只拷贝了值,浅拷贝
excel.name = "dddd"//修改值
print("姓名: \(clone.name)")//姓名: NSLog 只拷贝了基本的数据
结果
姓名: NSLog
-
案例二:深度拷贝->自定义协议
角色一:克隆接口
import Foundation
protocol CloneableProtocol {
associatedtype ObjType
func clone() -> ObjType
}
角色二:具体实现
//
// ValueModel.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class ValueModel: CloneableProtocol {
var name:String
var sex:String
init(name:String, sex:String) {
self.name = name
self.sex = sex
}
func clone() -> ValueModel {
return ValueModel(name: self.name, sex: self.sex)
}
}
//
// WorldDocument.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class WorldDocument: CloneableProtocol {
var name:String
var content:String
var value:ValueModel
init(name:String, content:String, value:ValueModel) {
self.name = name
self.content = content
self.value = value
}
func clone() -> WorldDocument {
return WorldDocument(name: self.name, content: self.content, value: self.value.clone())
}
}
调用
let value = ValueModel(name: "道道明明白白", sex: "男")
let world = WorldDocument(name: "NSLog", content: "NSError", value: value)
let clone = world.clone()
value.name = "ZBC"//深度拷贝,处于不同对象,所以这里修改clone不会发生改变
print("姓名: \(clone.value.name)")//姓名: 道道明明白白
-
案例三:系统协议
//
// NSLog.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class NSLog: NSCopying {
var name:String
var sex:String
init(name:String, sex:String) {
self.name = name
self.sex = sex
}
//Any也是一种类型->Swift
//自己看一下基础语法(Any->很多奥秘)
func copy(with zone: NSZone? = nil) -> Any {
return NSLog(name: self.name, sex: self.sex)
}
}
调用
//系统自带克隆协议
let nslog = NSLog(name: "NSError", sex: "男")
let copy = nslog.copy() as! NSLog
copy.name = "木木"
print("姓名: \(copy.name)")
- 案例五:克隆模式适用于子类继承父类并且增加属性
解决繁复的判断问题
//
// Order5.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class Order5: NSObject, CloneableProtocol {
var name:String
//方法重载,没有重写
init(name:String) {
self.name = name
super.init()
}
func clone() -> Order5 {
return Order5(name: self.name)
}
}
//
// PayOrder5.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class PayOrder5: Order5 {
var chennl:String
init(name: String, chennl:String) {
self.chennl = chennl
super.init(name: name)
}
override func clone() -> PayOrder5 {
return PayOrder5(name: self.name, chennl: self.chennl)
}
}
//
// OrderService5.swift
// Dream_20180716_Cloneable
//
// Created by Dream on 2018/7/16.
// Copyright © 2018年 Tz. All rights reserved.
//
import Cocoa
class OrderService5: NSObject {
private var array = Array<Order5>()
//父类的引用指向子类的实例对象
func add(order: Order5){
//克隆模式
self.array.append(order.clone())
}
//打印
func printOrder(callback:(Order5)->Void) {
for order in self.array {
callback(order)
}
}
}
let orderSerice = OrderService5()
let order = PayOrder5(name: "NSError", chennl: "支付宝")
orderSerice.add(order: order)
order.name = "NSError"
//同一个对象
orderSerice.printOrder { (o) in
//记录日志(客户端转换类型即可)
let pay = o as! PayOrder5 //客户端调用的时候指定类型
print(pay.chennl)
}
网友评论