分享最热门的ios资讯
转自:Sindri的小巢(简书)
设计模式(Design pattern)是一套被重复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。GoF提出了23种设计模式,本系列将使用Swift语言来实现这些设计模式。
概述
模板设计模式是最基础的设计模式之一,在网上被称作模板要领模式,但实际运用时这种设计模式却不仅仅局限于要领。因此笔者对于模板设计模式的理解界说如下:
【模板设计模式】将常见的要领以及工具成员进行封装,创建了一个实现一组抽象要领以及抽象工具成员作为工具实现使用的模板
坏味道的代码
在Swift中有个有趣的数据结构——元组Tuples,现在有这么一段代码。其中传入的每一个元祖表示某个商品的数据类型:
func calculateTax(product: (String, Double, Int)) -> Double { return product.1 * 0.17 } func calculateStockValue(products: [(String, Double, Int)]) -> Double { return products.reduce(0.0){ $0 + $1.1 * Double($1.2) } } override func viewDidLoad() { super.viewDidLoad() let products = [ ("Pizazz", 99.8, 10), ("Hamburger", 25.6, 8), ("Beef", 19.9, 30) ] print("The tax of \(products[0].1) is \(calculateTax(product[0]))") print("The stock value of all products is \(calculateStockValue(products))") }
上面的要领通过传入一个或者多个元组用来计算增值税(17%)以及商品存货总额。毫无疑问,对于稍有经验的开发者来说,都能说出这段代码有太大的坏味道了:两个要领过度的依赖于传入的元组结构,这意味着几乎无法复用这些要领
高耦合关系
模板设计模式
在开发语言从面向过程生长到面向工具的过程中,高级语言以及开发框架早已倒霉用各种设计模式进行了封装,我们在不知不觉中享受着这种封装带来的便倒霉却不自知。上方代码中的坏味道主要因为参数类型以及参数值受到限制,为了制止这种坏味道出现,通常使用模板设计模式来解决过高的耦合度。
Swift的模板设计模式
在Swift中,模板设计模式通过使用class和struct两种数据类型作为类工具的创建结构模板,用来创建差别内容的具体工具。因此改变之后的代码如下:
func calculateTax(product: Product) -> Double { return product.price * 0.17 } func calculateStockValue(products: [Product]) -> Double { return products.reduce(0){ return $0 + $1.price * Double($1.stock) } } class Product { var name: String var price: Double var stock: Int init(name: String, price price: Double, stock stock: Int) { self.name = name self.price = price self.stock = stock } }
通过以class结构为模板,我们可以创建各种差别属性的商品。虽然在界说class结构的过程中增加了一些分外的工作,但一来这使得我们的代码越发符合OOP的编程思想,二来解除了要领和元组之间的高度耦合。但这样的代码仍然存在另一个耦合问题——要领和类之间的耦合。如果有一天,项目需要面对全球市场,但是在差别的国家税种差别、税率也差别,这段代码也就有了另外的坏味道。因此我们需要把这两个要领同样放到class结构中成为要领模板
class Product { var name: String var price: Double var stock: Int init(name: String, price price: Double, stock stock: Int) { self.name = name self.price = price self.stock = stock } private func calculateTax() -> Double { return price * 0.17 } private func calculateStockValue() -> Double { return price * Double(stock) } func log() { print("The tax of \(name) is \(calculateTax())") print("The stock value of product is \(calculateStockValue())") } } class Product_Japan: Product { override private calculateTax() -> Double { return price * 0.05 } }
将要领抽象封装到父类中,并在子类中重写具体实现,这是模板要领模式的典型做法
模板要领模式
为了计算差别地区的税率要实现多个这样的子类的做法带来的代码量也是十分可观的,而且当税率成了一个可改变的因素时,要领可以改酿成为接收税率进行计算:
func calculateTax(ratio: Double) -> Double { return price * ratio }
总结
模式优点
将不变的行为抽离封装起来,去除了重复代码
通过子类重写父类实现,可以扩展面目目样的行为
模式缺点
class和struct都能倒霉用模板模式来解除高耦合,但两者在传递时采用差别的方式,这容易引发错误
容易造成子类的数量暴增,导致代码设计越发抽象
用意志战胜身体的惰性!
本文由 姬長信 创作,文章地址:https://blog.isoyu.com/archives/543.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:6 月 30, 2016 at 08:00 上午