You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+189Lines changed: 189 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1297,3 +1297,192 @@ If you are trying to use the same code for building different products to isolat
1297
1297
1298
1298
Also be careful that when your product does not require multiple parameters for initialisation or construction, it’s advised to stay away from Builder pattern.
1299
1299
1300
+
**8) Creational - Prototype Design Pattern:**
1301
+
1302
+
Definition:
1303
+
1304
+
Prototype is a creational design pattern used in situations which lets us produce new objects, that are almost similar state or differs little. A prototype is basically a template of any object before the actual object is constructed. The Prototype pattern delegates cloning process to objects themselves.
1305
+
1306
+
Usage:
1307
+
1308
+
Let us consider a simple use case where we want to create the profile of two cricketers which includes their name, and a custom profile which includes runs scored and wickets taken.
First, we create a Profile class which conforms to CustomStringConvertible. It has two properties runsScored and wicketsTaken of type int. It takes the same parameters during its initialisation.
1330
+
1331
+
Then we define a Cricketer class conforms to CustomStringConvertible. It has two properties, name of type String and profile of custom type Profile which we just created.
1332
+
1333
+
```
1334
+
class Cricketer : CustomStringConvertible {
1335
+
var name : String
1336
+
var profile : Profile
1337
+
1338
+
init(_ name :String , _ profile : Profile) {
1339
+
self.name = name
1340
+
self.profile = profile
1341
+
}
1342
+
var description: String{
1343
+
return "\(name) : Profile : \(profile)"
1344
+
}
1345
+
1346
+
}
1347
+
```
1348
+
1349
+
Let us now write a function called main to see the things in action.
1350
+
1351
+
```
1352
+
func main (){
1353
+
let profile = Profile(1200, 123)
1354
+
let bhuvi = Cricketer("Bhuvi", profile)
1355
+
print(bhuvi.description)
1356
+
}
1357
+
1358
+
main()
1359
+
```
1360
+
1361
+
It prints
1362
+
1363
+
Bhuvi : Profile : 1200 Runs Scored & 123 Wickets Taken in the Xcode console.
1364
+
1365
+
Now we need to talk about copying the objects.
1366
+
1367
+
Just before print statement in the main function, add the following lines .
Now, we need to make sure bhuvi and ishant actually refer to different objects.
1393
+
1394
+
Here, we use the concept of Deep Copy. When we deep copy objects, the system will copy references and each copied reference will be pointing to its own copied memory object. Let us now see how to implement Deep Copy interface for our use case.
1395
+
1396
+
```
1397
+
protocol DeepCopy{
1398
+
func createDeepCopy () -> Self
1399
+
}
1400
+
1401
+
```
1402
+
1403
+
First, we create a DeepCopy protocol which defines a function called createDeepCopy returning self.
1404
+
1405
+
Then make the classes Profile and Cricketer conform to DeepCopy protocol. Classes now look like:
1406
+
1407
+
```
1408
+
class Profile : CustomStringConvertible, DeepCopy{
We have a private method called deepCopyImplementation which is generic and and able to figure out the type correctly. It has a type parameter ‘T’ which is actually going to be inferred (we don’t provide this type parameter anywhere) and a return type of ‘T’. We return a Profile objects and force cast it to T.
1432
+
1433
+
Cricketer class now looks like:
1434
+
1435
+
```
1436
+
class Cricketer : CustomStringConvertible ,DeepCopy{
1437
+
var name : String
1438
+
var profile : Profile
1439
+
1440
+
init(_ name :String , _ profile : Profile) {
1441
+
self.name = name
1442
+
self.profile = profile
1443
+
}
1444
+
1445
+
var description: String{
1446
+
return "\(name) : Profile : \(profile)"
1447
+
}
1448
+
1449
+
func createDeepCopy() -> Self {
1450
+
return deepCopyImplementation()
1451
+
}
1452
+
1453
+
private func deepCopyImplementation <T> () -> T{
1454
+
return Cricketer(name, profile) as! T
1455
+
}
1456
+
1457
+
}
1458
+
```
1459
+
Let us define our main method as below and see the results:
We can see that bhuvi and ishant are two different objects now and this is how deep copy is implemented.
1482
+
1483
+
Summary:
1484
+
1485
+
When you are in a situation to clone objects without coupling to their concrete classes, you can opt for Prototype design pattern which also helps in reducing repetitive initialization code.
0 commit comments