# Swift in practice: the template pattern

Language: en
Canonical: [Swift in practice: the template pattern](<https://allluckly.cn/en/journal/2016-06-29-swift-in-practice-the-template-pattern/>)
中文：[中文 HTML](<https://allluckly.cn/%E6%8A%95%E7%A8%BF/tuogao51>)
English: [English HTML](<https://allluckly.cn/en/journal/2016-06-29-swift-in-practice-the-template-pattern/>)
Published: 2016-06-29T00:00:00+08:00
Modified: 2026-10-23T10:52:08+08:00
Author: Sindri

Uses product data and calculations to examine code that depends on a tuple's structure. Types and protocols then organise reusable processing, showing how abstraction can reduce coupling between parameter formats and business methods.

Originally credited to Sindri; edited and archived by Bison.

[Source listed in the original](<http://www.jianshu.com/p/76d38ceb1ad3>)

English translation of the [Chinese original](<https://allluckly.cn/%E6%8A%95%E7%A8%BF/tuogao51>), translated on 2026-10-23. The article body uses automated translation; app descriptions, historical reading notes and video subtitles receive separate editorial checks. Original publication dates, attribution, code and version notes are retained.

**Before you read** This technical note dates from 2015–2017. The examples have not been rerun as part of this archive update. Read API, dependency and tool details in the context of the original publication date.

![1](<https://allluckly.cn/images/blog/tuogao/tougao51/1.png>)

> Design patterns are classified, widely known, repeatedly used solutions distilled from code-design experience. The GoF proposed 23 patterns; this series implements them in Swift.

Editor: [Bison](<https://allluckly.cn/en/>)  
 Contributor: [Sindri’s Notes](<http://www.jianshu.com/p/76d38ceb1ad3>)

## Overview

The template design pattern is one of the most basic patterns. Online, it is commonly called the `模板方法模式`, but in practice its application is not limited to methods. My own definition is therefore:

> \[Template design pattern\] Encapsulate common methods and object members in a template providing abstract methods and members for concrete implementations.

## Code smells

Swift has an interesting data structure, `元组Tuples`. In the following code, each tuple passed in represents the data for a product:

```
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%）以及商品存货总额。毫无疑问，对于稍有经验的开发者来说，都能说出这段代码有太大的`坏味道`了：两个方法过度的依赖于传入的元组结构，这意味着几乎无法复用这些方法
```

![1](<https://allluckly.cn/images/blog/tuogao/tougao51/2.jpg>)

## Template design pattern

As languages evolved from procedural to object-oriented programming, high-level languages and frameworks encapsulated many design patterns. We often benefit from this without noticing. The `坏味道` in the code above comes mainly from restrictions on parameter types and values. To avoid this `坏味道`, a common approach is to use `模板设计模式` to reduce excessive coupling.

![1](<https://allluckly.cn/images/blog/tuogao/tougao51/3.jpg>)

In Swift, the template design pattern uses `class` and `struct` as structural templates for creating concrete objects with different contents. The revised code is:

```
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
    }
}
```

Using a `class` structure as the template, we can create products with different properties. Defining the `class` adds some work, but makes the code more consistent with `OOP` and removes the tight coupling between methods and tuples. Another coupling remains, however, between methods and classes. If the project later serves global markets with different tax types and rates, the code acquires another `坏味道`. We therefore also need to move these two methods into the `class` structure as method templates.

```
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
    }
}
```

Abstracting methods into a superclass and overriding their concrete implementations in subclasses is a typical use of `模板方法模式`.

![1](<https://allluckly.cn/images/blog/tuogao/tougao51/4.jpg>)

Implementing multiple subclasses for regional tax rates creates substantial code. When the rate becomes a variable, change the method to accept it:

```
func calculateTax(ratio: Double) -> Double {
    return price * ratio
}
```

## Summary

> Pattern advantages

- Extract and encapsulate invariant behaviour, removing duplicated code.
- Subclasses override superclass implementations to add new behaviour.

> Pattern disadvantages

- Both `class` and `struct` can use the template pattern to reduce coupling, but their different passing semantics can cause errors.
- can cause an explosion of subclasses and make the design more abstract.

---

Recommended reading: [Adding a launch advertisement to an iOS app](<https://allluckly.cn/en/journal/2016-06-12-adding-a-launch-advertisement-to-an-ios-app/>)

