3232
3333#### Element:
3434
35- Defines the protocol that accepts different types of discount visitors.
35+ - Defines the protocol that accepts different types of discount visitors.
36+
37+ - Products are will be accepting visitors, so we define each roles involved in the Element.
3638
3739``` swift
38- protocol DiscountVisitorAccepting {
39- func acceptVisitor (_ visitor : DiscountVisitor)
40+ public protocol Product {
41+ var id: String { get }
42+ var price: Double { get }
43+ }
44+
45+ public protocol VisitorAccepting {
46+ func accept <V : Visitor >(_ visitor : V) -> V.VisitorResult
4047}
4148```
4249
@@ -45,70 +52,68 @@ protocol DiscountVisitorAccepting {
4552Concrete product types that accept a visitor according to the protocol defined above.
4653
4754``` swift
48- struct MacBookProProduct : DiscountVisitorAccepting {
55+ struct MacBookProProduct : Product , VisitorAccepting {
4956 let id: String
5057 let price: Double
5158
52- func acceptVisitor (_ visitor : DiscountVisitor) {
53- visitor.visitMacBookPro (self )
59+ func accept < V : Visitor > (_ visitor : V) -> V.VisitorResult {
60+ visitor.visit (self )
5461 }
5562}
5663
57- struct VisionProProduct : DiscountVisitorAccepting {
64+ struct VisionProProduct : Product , VisitorAccepting {
5865 let id: String
5966 let price: Double
6067
61- func acceptVisitor (_ visitor : DiscountVisitor) {
62- visitor.visitVisionPro (self )
68+ func accept < V : Visitor > (_ visitor : V) -> V.VisitorResult {
69+ visitor.visit (self )
6370 }
6471}
6572```
6673
6774#### Visitor:
6875
69- Defines the discount calculation methods for each product type.
76+ - Defines the visitor protocol that will be implemented by concrete visitors.
77+
78+ - We are able to define the return type via the use of an associated type.
7079
7180``` swift
72- protocol DiscountVisitor {
73- func visitMacBookPro ( _ macBookPro : MacBookProProduct)
74- func visitVisionPro (_ visionPro : VisionProProduct)
81+ protocol Visitor {
82+ associatedtype VisitorResult
83+ func visit (_ product : Product) -> VisitorResult
7584}
7685```
7786
7887#### Concrete visitors:
7988
80- - Implements the discount calculations for each product type .
89+ - Concrete visitors that implement the visitor protocol .
8190
82- - Education discount is 25%.
83-
84- - Employee discount is 50%.
91+ - We have three discount types: education and employee discounts, and a description visitor.
8592
8693``` swift
87- class EducationDiscountVisitor : DiscountVisitor {
94+ class EducationDiscountVisitor : Visitor {
95+ typealias VisitorResult = Double
8896 private let discountPercentage = 0.25
89- private (set ) var macBookProDiscount = 0.0
90- private (set ) var visionProDiscount = 0.0
91-
92- func visitMacBookPro (_ macBookPro : MacBookProProduct) {
93- macBookProDiscount = macBookPro.price * discountPercentage
94- }
9597
96- func visitVisionPro (_ visionPro : VisionProProduct) {
97- visionProDiscount = visionPro .price * discountPercentage
98+ func visit (_ product : Product) -> Double {
99+ product .price * discountPercentage
98100 }
99101}
100102
101- class EmployeeDiscountVisitor : DiscountVisitor {
103+ class EmployeeDiscountVisitor : Visitor {
104+ typealias VistorResult = Double
102105 private let discountPercentage = 0.5
103- private (set ) var macBookProDiscount = 0.0
104- private (set ) var visionProDiscount = 0.0
105106
106- func visitMacBookPro (_ macBookPro : MacBookProProduct) {
107- macBookProDiscount = macBookPro .price * discountPercentage
107+ func visit (_ product : Product) -> Double {
108+ product .price * discountPercentage
108109 }
110+ }
109111
110- func visitVisionPro (_ visionPro : VisionProProduct) {
111- visionProDiscount = visionPro.price * discountPercentage
112+ class DescriptionVisitor : Visitor {
113+ typealias VisitorResult = String
114+
115+ func visit (_ product : Product) -> String {
116+ " Product with ID \( product.id ) costs $\( product.price ) "
112117 }
113118}
114119```
@@ -117,20 +122,19 @@ class EmployeeDiscountVisitor: DiscountVisitor {
117122
118123``` swift
119124// Education discount for MacBook Pro
120-
121125let educationDiscountVisitor = EducationDiscountVisitor ()
122-
123126let macBookProProduct = MacBookProProduct (id : " 1" , price : 1000.00 )
124- macBookProProduct.acceptVisitor (educationDiscountVisitor)
125-
126- print (educationDiscountVisitor.macBookProDiscount ) // 250.00
127+ let macBookProEducationDiscount = macBookProProduct.accept (educationDiscountVisitor)
128+ print (macBookProEducationDiscount) // 250.00
127129
128130// Employee discount for Vision Pro
129-
130131let employeeDiscountVisitor = EmployeeDiscountVisitor ()
131-
132- let visionProProduct = VisionProProduct (id : " 1" , price : 10000.00 )
133- visionProProduct.acceptVisitor (employeeDiscountVisitor)
134-
135- print (employeeDiscountVisitor.visionProDiscount ) // 5000.00
132+ let visionProProduct = VisionProProduct (id : " 2" , price : 10000.00 )
133+ let visionProEmployeeDiscount = visionProProduct.accept (employeeDiscountVisitor)
134+ print (visionProEmployeeDiscount) // 5000.00
135+
136+ // Description for MacBook Pro
137+ let descriptionVisitor = DescriptionVisitor ()
138+ let macBookProDescription = macBookProProduct.accept (descriptionVisitor)
139+ print (macBookProDescription) // Product with ID 1 costs $1000.0
136140```
0 commit comments