A primary customer instance
The visitor design pattern is among the behavioral patterns, it’s used to increase an object with a given performance with out really modifying it. Sounds cool, proper? Truly this sample is what offers SwiftUI superpowers, let me present you the way it works.
open class View
remaining class FirstView: View
remaining class SecondView: View
remaining class ThirdView: View
struct HeightVisitor
func go to(_ view: FirstView) -> Float 16
func go to(_ view: SecondView) -> Float 32
func go to(_ view: ThirdView) -> Float 64
protocol AcceptsHeightVisitor
func settle for(_ customer: HeightVisitor) -> Float
extension FirstView: AcceptsHeightVisitor
func settle for(_ customer: HeightVisitor) -> Float customer.go to(self)
extension SecondView: AcceptsHeightVisitor
func settle for(_ customer: HeightVisitor) -> Float customer.go to(self)
extension ThirdView: AcceptsHeightVisitor
func settle for(_ customer: HeightVisitor) -> Float customer.go to(self)
let customer = HeightVisitor()
let view1: AcceptsHeightVisitor = FirstView()
let view2: AcceptsHeightVisitor = SecondView()
let view3: AcceptsHeightVisitor = ThirdView()
print(view1.settle for(customer))
print(view2.settle for(customer))
print(view3.settle for(customer))
First we outline our customized view lessons, this may assist to visualise how the sample works. Subsequent we outline the precise HeightVisitor
object, which can be utilized to calculate the peak for every view sort (FirstView, SecondView, ThirdView). This fashion we do not have to change these views, however we are able to outline a protocol AcceptsHeightVisitor
, and prolong our lessons to just accept this customer object and calculate the consequence utilizing a self pointer. 👈
On the decision facet we are able to provoke a brand new customer occasion and easily outline the views utilizing the protocol sort, this fashion it’s attainable to name the settle for customer methodology on the views and we are able to calculate the peak for every sort with out altering the inner construction of those lessons.
A generic customer
We will additionally make this sample extra generic by making a Swift protocol with an related sort.
open class View
remaining class FirstView: View
remaining class SecondView: View
remaining class ThirdView: View
struct HeightVisitor
func go to(_ view: FirstView) -> Float 16
func go to(_ view: SecondView) -> Float 32
func go to(_ view: ThirdView) -> Float 64
protocol Customer
associatedtype R
func go to<O>(_ object: O) -> R
protocol AcceptsVisitor
func settle for<V: Customer>(_ customer: V) -> V.R
extension AcceptsVisitor
func settle for<V: Customer>(_ customer: V) -> V.R customer.go to(self)
extension FirstView: AcceptsVisitor
extension SecondView: AcceptsVisitor
extension ThirdView: AcceptsVisitor
extension HeightVisitor: Customer
func go to<O>(_ object: O) -> Float
if let o = object as? FirstView
return go to(o)
if let o = object as? SecondView
return go to(o)
if let o = object as? ThirdView
return go to(o)
fatalError("Go to methodology unimplemented for sort (O.self)")
let customer = HeightVisitor()
let view1: AcceptsVisitor = FirstView()
let view2: AcceptsVisitor = SecondView()
let view3: AcceptsVisitor = ThirdView()
print(view1.settle for(customer))
print(view2.settle for(customer))
print(view3.settle for(customer))
You need to use the generic Customer
protocol to outline the customer and the AcceptsVisitor
protocol to simply prolong your objects to just accept a generic customer sort. When you select this method you continue to need to implement the generic go to methodology on the Customer, forged the article sort and name the sort particular go to methodology. This fashion we moved the go to name logic into the customer. 🙃
Because the views already conforms to the AcceptsVisitor
protocol, we are able to simply prolong them with different guests. For instance we are able to outline a coloration customer like this:
struct ColorVisitor: Customer
func go to(_ view: FirstView) -> String "pink"
func go to(_ view: SecondView) -> String "inexperienced"
func go to(_ view: ThirdView) -> String "blue"
func go to<O>(_ object: O) -> String
if let o = object as? FirstView
return go to(o)
if let o = object as? SecondView
return go to(o)
if let o = object as? ThirdView
return go to(o)
fatalError("Go to methodology unimplemented for sort (O.self)")
let customer = ColorVisitor()
let view1: AcceptsVisitor = FirstView()
let view2: AcceptsVisitor = SecondView()
let view3: AcceptsVisitor = ThirdView()
print(view1.settle for(customer))
print(view2.settle for(customer))
print(view3.settle for(customer))
As you may see it is fairly good that we are able to obtain this type of dynamic object extension logic by way of guests. If you wish to see a sensible UIKit instance, be happy to try this article. Beneath the hood SwiftUI closely makes use of the customer sample to realize some magical TupleView & ViewBuilder related stuff. This sample is so cool, I extremely suggest to study extra about it. 💪