設計模式學習-物件模板模式

敖老黑發表於2017-12-21

物件模板模式其實就是物件導向程式設計。

假設我們要管理一個產品,需要有產品的名稱,產品描述,單價,和庫存個數。其次需要兩個方法,一個用於計算每件產品的稅費是多少,另一個計算剩餘庫存的總價格

首先建立一個命令列程式。在main.swift檔案裡初始化下面程式碼

var products = [
    ("kayak","A boat for one person",275.0,10),
    ("LifeJacket","Protective and fashionable",48.95,14),
    ("Soccer Ball","FIFA-aoorived suze abd weight",19.5,32)
]


func caculateTax(product:(String,String,Double,Int)) -> Double{
    return product.2*0.2
}

func caculateStockValue(tuples:[(String,String,Double,Int)]) -> Double{
    return tuples.reduce(0, { (total, product) -> Double in
        return total + (product.2 * Double(product.3))
    })
}

print("Sales tax for kayak:$\(caculateTax(product: products[0]))")

print("Total value of stock:$\(caculateStockValue(tuples: products))")
複製程式碼

上面程式碼簡單實現了需求,但是可以看到使用元組實現該需求帶來的一些問題,如果給產品增加一個屬性,那麼連帶修改的地方有很多。而且不易於理解元組中每一個元素代表什麼

下面我們使用物件模板模式修改上面程式碼,新建Product.swift檔案

class Product {
    var name:String
    var description:String
    var price:Double
    var stock:Int
    
    init(name:String,description:String,price:Double,stock:Int) {
        self.name = name
        self.description = description
        self.price = price
        self.stock = stock
    }
}
複製程式碼

修改main.swift

var products = [
    Product(name: "kayak", description: "A boat for one person", price: 275.0, stock: 10),
    Product(name: "LifeJacket", description: "Protective and fashionable", price: 48.95, stock: 14),
    Product(name: "Soccer Ball", description: "FIFA-aoorived suze abd weight", price: 19.5, stock: 32)
]


func caculateTax(product:Product) -> Double {
    return product.price * 0.2
}

func caculateStockValue(tuples:[Product]) -> Double{
    return tuples.reduce(0, { (total, product) -> Double in
        return total + (product.price * Double(product.stock))
    })
}

print("Sales tax for kayak:$\(caculateTax(product: products[0]))")

print("Total value of stock:$\(caculateStockValue(tuples: products))")
複製程式碼

上面修改完成之後,其實已經可以看到的是程式碼的閱讀性明顯提高,一看就知道每一個引數代表什麼。此時如果我們去除某一個產品屬性,比如描述description屬性,也不需要修改呼叫者的邏輯。

下面為最終修改

class Product {
    var name:String
    var price:Double
    
    private var stockBackingValue:Int = 0
    
    var stock:Int{
        get{
            return stockBackingValue
        }
        set{
            stockBackingValue = max(0, newValue)
        }
    }
    
    var stockValue:Double{
        get{
            return price * Double(stock)
        }
    }

    init(name:String,price:Double,stock:Int) {
        self.name = name
        self.price = price
        self.stock = stock
    }
    
    func calculateTax(rate:Double) -> Double {
        return price * rate
    }
    
    
}

複製程式碼

main.swift 的修改

var products = [
    Product(name: "kayak", price: 275.0, stock: 10),
    Product(name: "LifeJacket", price: 48.95, stock: 14),
    Product(name: "Soccer Ball", price: 19.5, stock: 32)
]


func caculateStockValue(tuples:[Product]) -> Double{
    return tuples.reduce(0, { (total, product) -> Double in
        return total + (product.price * Double(product.stockValue))
    })
}

print("Sales tax for kayak:$\(products[0].calculateTax(rate: 0.2))")

print("Total value of stock:$\(caculateStockValue(tuples: products))")

products[0].stock = -50

print("Stock level for kayak :\(products[0].stock)")

複製程式碼

物件模板的好處和注意點:

  • 解耦
  • 封裝使資料和操作這些值的邏輯能夠再一個單一元件中,提高程式碼的可讀性
  • 要避免選錯模板型別(類和結構體),結構體為值型別,類為引用型別,選擇時應注意其區別

示例程式碼在這裡github.com/RockyAo/Des…

相關文章