Swift design mode: Object template mode and swift Design Mode
Application scenarios:
Raw data is tightly coupled with usage
For example:
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 }) }
At this time, the raw data is tightly coupled with the use. Once the raw data is changed, such as the deletion, the usage will be directly affected, such as the deletion of the price.
Solution: Use the object template Mode
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 })
In this way, when I delete the price, I only need to change the product without changing its usage, achieving the goal of decoupling.
Further Optimization: Encapsulation
Encapsulation is one of the core ideas of object-oriented programming.
Encapsulation enables the logic of data values and operation data values to be combined in a single component.
The following describes how to encapsulate the data value and the logic of the operation data value.
The total inventory value is required.
product.stock*product.price
Therefore, change the Product as follows:
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 }) }
Exposing attributes or methods to the outside without exposing internal implementations makes decoupling very simple.
At this time, if I want to modify the calculation method of the stockvalue, the outside world will not know and will not affect it.
We can also make some modifications, such:
You don't want to directly change the product name, price, and inventory.
private(set) var name: String! private(set) var price: Int! private(set) var stock: Int!
However, the outside world wants an interface for changing inventory, and you must ensure that the inventory quantity is greater than 0:
Another computing attribute needs to be introduced.
private var stockBackingValue: Int = 0 var stock: Int{ get { return stockBackingValue; } set { stockBackingValue = max(0, newValue); } }
Final code:
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)) }
The object template mode is the core mode in Swift development.
The advantage of this mode is that it provides some basic tools for decoupling.
In addition, this mode can be used to hide the internal implementation of an object and provide a public API to the external object.