-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathLsp.cs
130 lines (114 loc) · 3.4 KB
/
Lsp.cs
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System;
using System.Collections.Generic;
using Solid.OpenClosed;
namespace Solid.Liskov
{
class Lsp : IPrinciple
{
public string Principle()
{
return "Liskov Substitution";
}
// BAD: Violating Liskov substitution principle
// The parent should easily the replace the child object and not break any functionality, only lose some.
// e.g. here, we don't want this to add an enquiry so we have to throw
// a new exception, that is violating the principle
class Enquiry : Customer
{
public override int Discount(int sales)
{
return this.BaseDiscount - (sales * 5);
}
public override void Add(Database db)
{
throw new Exception("Not allowed");
}
}
// e.g. to show how this is bad:
public class GoldCustomer : Customer
{
public override int Discount(int sales)
{
return BaseDiscount - sales - 100;
}
}
public class SilverCustomer : Customer
{
public override int Discount(int sales)
{
return BaseDiscount - sales - 50;
}
}
class ViolatingLiskovs
{
public void ParseCustomers()
{
var database = new Database();
var customers = new List<Customer>
{
new GoldCustomer(),
new SilverCustomer(),
new Enquiry() // This is valid
};
foreach (Customer c in customers)
{
// Enquiry.Add() will throw an exception here!
c.Add(database);
}
}
}
// Better method:
interface IDiscount
{
int Discount(int sales);
}
interface IDatabase
{
void Add(Database db);
}
internal class BetterCustomer : IDiscount, IDatabase
{
public virtual int Discount(int sales)
{
return sales;
}
public void Add(Database db)
{
db.Add();
}
}
internal class BetterGoldCustomer : BetterCustomer
{
public override int Discount(int sales)
{
return sales - 100;
}
}
internal class BetterSilverCustomer : BetterCustomer
{
public override int Discount(int sales)
{
return sales - 50;
}
}
// GOOD: Now, we don't violate Liskov Substitution principle
class AdheringToLiskovs
{
public void ParseCustomers()
{
var database = new Database();
var customers = new List<BetterCustomer>
{
new BetterGoldCustomer(),
new BetterSilverCustomer(),
// new Enquiry() // This will give a compiler error, rather than runtime error
};
foreach (BetterCustomer c in customers)
{
// Enquiry.Add() will throw an exception here!
c.Add(database);
}
}
}
}
}