应用场景:
原始数据与使用存在紧耦合
如:
var products = [("computer",10000,200),("book",10,2000)]
func calculateAllStock(products: [(String,Int,Int)]) -> Int {
return products.reduce(0, { (total, product) -> Int in
return total + product.1*product.2
})
}
这时的原始数据与使用存在了紧耦合,一旦更改了原始数据,比如删除,那么会直接影响使用的地方,比如删除了价格price
解决:使用对象模板模式
class Product{
var name: String!
var price: Int!
var stock: Int!
init(name:String,price:Int,stock:Int) {
self.name = name
self.price = price
self.stock = stock
}
}
var products = [Product.init(name: "computer", price: 10000, stock: 200),Product.init(name: "book", price: 10, stock: 2000)]
func calculateAllStockValue(products: [Product]) -> Int {
return products.reduce(0, { (total, product) -> Int in
return total + product.stock*product.price
})
这样当我删除价格的时候,只需要更改product,而不需要更改他的使用的地方,达到了解耦的目的。
进一步优化:封装
封装是面向对象的编程的和核心思想之一。
封装使得数据值,与操作数据值的逻辑能够结合在单一组件中。
下面将数据值,与操作数据值的逻辑放到一起达到封装的目的。
由于,外界需要库存总价值
product.stock*product.price
所以,更改Product如下:
class Product{
var name: String!
var price: Int!
var stock: Int!
var stockValue:Int{
get{return price*stock}
}
init(name:String,price:Int,stock:Int) {
self.name = name
self.price = price
self.stock = stock
}
}
func calculateAllStockValue(products: [Product]) -> Int {
return products.reduce(0, { (total, product) -> Int in
return total + product.stockValue
})
}
将属性或者方法暴露给外界,但是又不暴露内部实现,让解耦变得十分简单
这时,如果我想要修改stockvalue的值的计算方式,那么外界也不会知道,也不会影响到。
我们还可以做一些修改,比如:
你不想外界直接更改product的名字,价格,库存。
private(set) var name: String!
private(set) var price: Int!
private(set) var stock: Int!
但是外界希望有更改库存的接口,而且你自己需要保证库存数量大于0:
需要引入另一个计算属性
private var stockBackingValue: Int = 0
var stock: Int{
get {
return stockBackingValue;
}
set {
stockBackingValue = max(0, newValue);
}
}
最终代码:
class Product{
private(set) var name: String!
private(set) var price: Int!
private var stockBackingValue: Int = 0
var stock: Int{
get {
return stockBackingValue;
}
set {
stockBackingValue = max(0, newValue);
}
}
var stockValue:Int{
get{return price*stock}
}
init(name:String,price:Int,stock:Int) {
self.name = name
self.price = price
self.stock = stock
}
}
var products = [Product.init(name: "computer", price: 10000, stock: 200),Product.init(name: "book", price: 10, stock: 2000)]
func calculateAllStockValue(products: [Product]) -> Int {
return products.reduce(0, { (total, product) -> Int in
return total + product.stockValue
})
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
print(calculateAllStockValue(products: products))
}
对象模板模式,是Swift开发中处于核心地位的模式。
这个模式的优点是为我们提供了一些用于解耦的基本工具。
此外,使用该模式可以隐藏对象内部的实现的情况下,向外界对象提供一个公开的API。