Swift: Protocol Composition š
I’ve been incorporatingĀ Protocol-Oriented Programming more and more in my Swift code and I LOVE it!!! Thanks again to @mhollemansĀ for the article onĀ Mixins and Traits in Swift 2.0Ā – that really helped meĀ understand how to use protocols in a very powerful and beautiful way.
However, I’ve found that in practice, my objects sometimes conform to too many protocols, so the method or classes that take in these protocols become way too long and a bit confusing, just like in the below configure method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// SwitchWithTextTableViewCell.swift import UIKit protocol TextPresentable { var text: String { get } var textColor: UIColor { get } var font: UIFont { get } } protocol SwitchPresentable { var switchOn: Bool { get } var switchColor: UIColor { get } } protocol ImagePresentable { var imageName: String { get } } class SwitchWithTextTableViewCell: UITableViewCell { @IBOutlet private weak var label: UILabel! @IBOutlet private weak var switchToggle: UISwitch! @IBOutlet private weak var iconView: UIImageView! // Too long and a bit confusing! func configure<T where T: TextPresentable, T: SwitchPresentable, T: ImagePresentable>(presenter: T) { label.text = presenter.text switchToggle.on = presenter.switchOn switchToggle.onTintColor = presenter.switchColor iconView.image = UIImage(named: presenter.imageName) } } |
So one solution to this that I really like was suggested to me by @zachwaugh: Protocol Composition!!! It looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Protocol Composition!! typealias SwitchWithTextViewPresentable = protocol<TextPresentable, SwitchPresentable, ImagePresentable> class SwitchWithTextTableViewCell: UITableViewCell { @IBOutlet private weak var label: UILabel! @IBOutlet private weak var switchToggle: UISwitch! @IBOutlet private weak var iconView: UIImageView! func configure(presenter: SwitchWithTextViewPresentable) { label.text = presenter.text switchToggle.on = presenter.switchOn switchToggle.onTintColor = presenter.switchColor iconView.image = UIImage(named: presenter.imageName) } } |
I seriously love this š¤š. It is readable, avoids generics, and communicates the intention of the protocols very clearly. Thanks again @zachwaugh for suggesting it!