Skip to content

Commit d326ce2

Browse files
Update README.md
1 parent b97fa78 commit d326ce2

File tree

1 file changed

+234
-0
lines changed

1 file changed

+234
-0
lines changed

README.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3093,3 +3093,237 @@ Summary:
30933093

30943094
When you are in a situation where you want to hide the complexity of a data structure from clients and have a single interface for traversing the data structures, iterator design pattern serves you the best.
30953095

3096+
**21) Behavioral - Interpreter Design Pattern:**
3097+
3098+
Definition:
3099+
3100+
Interpreters are present everywhere around us. In design patterns, interpreter is a component that processes structured text data. It falls under behavioral design pattern.
3101+
3102+
Usage:
3103+
3104+
Let us use iterator design pattern to get a way to access the elements of a collection object in sequential manner without any need to know its underlying representation.
3105+
3106+
```
3107+
import UIKit
3108+
import Foundation
3109+
3110+
protocol Iterator{
3111+
func hasNext() -> Bool
3112+
func next() -> String
3113+
}
3114+
3115+
protocol Container{
3116+
func getIterator() -> Iterator
3117+
}
3118+
```
3119+
3120+
We define two protocols named Iterator and Container. Iterator has two functions to check if the there is next element present in array after every iteration and to return the element (if present). Container has a method to return the iterator.
3121+
3122+
```
3123+
class NameRepo : Container{
3124+
let names = ["India" ,"Australia", "England", "NewZealand"]
3125+
func getIterator() -> Iterator {
3126+
return NameIterator(names)
3127+
}
3128+
}
3129+
```
3130+
3131+
We then define a class called NameRepo conforming to Container protocol. In our main function, we use iterator to print all the values present in names array.
3132+
3133+
```
3134+
private class NameIterator : Iterator{
3135+
var index = -1
3136+
var names = [String]()
3137+
3138+
init(_ names : [String]){
3139+
self.names = names
3140+
}
3141+
3142+
func hasNext() -> Bool {
3143+
if index < names.count {
3144+
return true
3145+
}
3146+
return false
3147+
}
3148+
3149+
func next() -> String {
3150+
if self.hasNext(){
3151+
index = index + 1
3152+
return names[index]
3153+
} else{
3154+
return ""
3155+
}
3156+
}
3157+
}
3158+
```
3159+
3160+
We define a class called NameIterator conforming to Iterator protocol. It takes a parameter of type String array during its initialisation.
3161+
3162+
Let us write a main function to see the code in action:
3163+
3164+
```
3165+
func main(){
3166+
let nr = NameRepo()
3167+
let iterator = NameIterator(nr.names)
3168+
3169+
for _ in nr.names{
3170+
iterator.hasNext()
3171+
print(iterator.next())
3172+
}
3173+
}
3174+
3175+
main()
3176+
```
3177+
3178+
Output in the Xcode console:
3179+
3180+
India
3181+
Australia
3182+
England
3183+
NewZealand
3184+
3185+
**22) Behavioral - Mediator Design Pattern:**
3186+
3187+
3188+
Definition:
3189+
Mediator is a behavioural design pattern that lets us define a component that encapsulates relationships between a set of components (that absolutely makes no sense to have direct references to one another) to make them independent of each other. Mediator pattern prevents direct communication between individual components by sending requests to a central component which knows whom to redirect those requests.
3190+
Usage:
3191+
Let us assume we are designing a TV Umpire decision review system for a cricket match. When an on-field umpire does not have enough evidence to rule a batsman out, he sends the request to TV umpire who takes a look at the replays and sends a command to the Monitor operator who displays the final decision on the big screen in the ground.
3192+
Let’s see how we can use Mediator design pattern to design such decision review system.
3193+
3194+
```
3195+
import UIKit
3196+
import Foundation
3197+
3198+
protocol Command{
3199+
func displayStatus()
3200+
}
3201+
```
3202+
3203+
3204+
We write a protocol Command which defines a function called displayStatus.
3205+
3206+
```
3207+
protocol RemoteUmpire{
3208+
func registerTVDisplay(tvDisplay :TVDisplay)
3209+
func registerTVOperator(tvOperator : TVOperator)
3210+
func isDecisionMade() -> Bool
3211+
func setDecisionStatus(status : Bool)
3212+
}
3213+
```
3214+
3215+
We write another protocol called RemoteUmpire which defines handful of functionalities.
3216+
3217+
The remote umpire ( also called TV umpire) has to register for TV display by passing a parameter of type TVDisplay (to be defined).
3218+
The remote umpire ( also called TV umpire) has to register for TV operator by passing a parameter of type TVOperator (to be defined).
3219+
A function named isDecisionMade which returns a boolean.
3220+
Another function to set the status of decision by passing a boolean argument.
3221+
3222+
```
3223+
class TVOperator : Command{
3224+
var tvUmpire:TVUmpire
3225+
3226+
init(_ tvUmpire : TVUmpire){
3227+
self.tvUmpire = tvUmpire
3228+
}
3229+
3230+
func displayStatus() {
3231+
if tvUmpire.isDecisionMade(){
3232+
print("Decision Made and Batsman in OUT")
3233+
tvUmpire.setDecisionStatus(status: true)
3234+
} else{
3235+
print("Decision Pending")
3236+
}
3237+
}
3238+
3239+
func getReady(){
3240+
print("Ready to Display Decision")
3241+
}
3242+
}
3243+
```
3244+
3245+
We define a class called TVOperator conforming to Command protocol. It takes an object of type TVUmpire (to be defined) during its initialisation.
3246+
3247+
It has a method named displayStatus which based on tv umpire’s decision displays a batsman out or not on the big screen in the stadium.
3248+
3249+
```
3250+
class TVDisplay : Command{
3251+
var tvUmpire:TVUmpire
3252+
3253+
init(_ tvUmpire : TVUmpire) {
3254+
self.tvUmpire = tvUmpire
3255+
tvUmpire.setDecisionStatus(status: true)
3256+
}
3257+
3258+
func displayStatus() {
3259+
print("Decision made and permission granted to display the decision on TV Display")
3260+
tvUmpire.setDecisionStatus(status: true)
3261+
}
3262+
}
3263+
```
3264+
3265+
We define a class called TVDisplay conforming to Command protocol. This class also takes an object of type TVUmpire (to be defined) for its initialisation. Its main functionality is to display the status of decision based on the input given by TV umpire.
3266+
3267+
```
3268+
class TVUmpire : RemoteUmpire{
3269+
private var tvOperator : TVOperator?
3270+
private var tvDisplay : TVDisplay?
3271+
private var decisionMade : Bool?
3272+
3273+
func registerTVDisplay(tvDisplay: TVDisplay) {
3274+
self.tvDisplay = tvDisplay
3275+
}
3276+
3277+
func registerTVOperator(tvOperator: TVOperator) {
3278+
self.tvOperator = tvOperator
3279+
}
3280+
3281+
func isDecisionMade() -> Bool {
3282+
return decisionMade!
3283+
}
3284+
3285+
func setDecisionStatus(status: Bool) {
3286+
self.decisionMade = status
3287+
}
3288+
}
3289+
```
3290+
We then define our most important class named TVUmpire conforming to RemoteUmpire protocol. It has three private optional variables defined namely, tvOperator of type TVOperator, tvDisplay of type TYDisplay and a boolen named decisonMade.
3291+
3292+
It registers for TV display by assigning its property of tvDisplay to parameter of type TVDisplay from the method registerTVDisplay.
3293+
3294+
It registers for TV operator by assigning its property of tvOperator to parameter of type TVOperator from the method registerTVOperator.
3295+
3296+
Let’s now write our main function and see how the above code comes into action.
3297+
3298+
```
3299+
func main(){
3300+
let tvUmpire = TVUmpire()
3301+
let tvDisplayAtGround = TVDisplay(tvUmpire)
3302+
let tvOperatorAtGround = TVOperator(tvUmpire)
3303+
tvUmpire.registerTVDisplay(tvDisplay: tvDisplayAtGround)
3304+
tvUmpire.registerTVOperator(tvOperator: tvOperatorAtGround)
3305+
tvOperatorAtGround.getReady()
3306+
tvDisplayAtGround.displayStatus()
3307+
tvOperatorAtGround.displayStatus()
3308+
3309+
}
3310+
3311+
main()
3312+
```
3313+
3314+
3315+
We take an instance of TVUmpire and pass the same instance to initialise TVDisplay and TVOperator.
3316+
3317+
TVUmpire then registers for TVDisplay and TVUmpire by passing instances of TVDisplay and TVUmpire respectively.
3318+
3319+
Once the TV umpire has made his decision, TV operator at ground gets ready to display the status of decision accordingly on the display at ground.
3320+
3321+
Output in the Xcode console:
3322+
Ready to Display Decision
3323+
Decision made and permission granted to display the decision on TV Display
3324+
Decision Made and Batsman in OUT
3325+
3326+
Summary:
3327+
3328+
Use a mediator design pattern when the complexity of object communication begins to hinder object reusability. Mediator engages in two way communication with its connected components.
3329+

0 commit comments

Comments
 (0)