Skip to content

Commit ae6fb16

Browse files
authored
Merge pull request mouredev#4868 from hozlucas28/Solution-28-Go
#28 - Go
2 parents 76b8b2e + 2dea44e commit ae6fb16

File tree

1 file changed

+296
-0
lines changed

1 file changed

+296
-0
lines changed
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"math"
7+
)
8+
9+
/* -------------------------------------------------------------------------- */
10+
/* INTERFACES */
11+
/* -------------------------------------------------------------------------- */
12+
13+
type BadShape interface {
14+
GetArea() (float64, error)
15+
}
16+
17+
type GoodShape interface {
18+
GetArea() float64
19+
}
20+
21+
type Vehicle interface {
22+
Brake()
23+
SpeedUp()
24+
}
25+
26+
/* -------------------------------------------------------------------------- */
27+
/* FUNCTIONS */
28+
/* -------------------------------------------------------------------------- */
29+
30+
func BadGetArea(shape BadShape) (float64, error) {
31+
return shape.GetArea()
32+
}
33+
34+
func GoodGetArea(shape GoodShape) float64 {
35+
return shape.GetArea()
36+
}
37+
38+
func Brake(vehicle Vehicle) {
39+
vehicle.Brake()
40+
}
41+
42+
func SpeedUp(vehicle Vehicle) {
43+
vehicle.SpeedUp()
44+
}
45+
46+
/* -------------------------------------------------------------------------- */
47+
/* CLASSES */
48+
/* -------------------------------------------------------------------------- */
49+
50+
/* ------------------------------ BadRectangle ------------------------------ */
51+
52+
type badRectangle struct {
53+
Height float64
54+
Width float64
55+
_ struct{}
56+
}
57+
58+
func NewBadRectangle(height float64, width float64) BadShape {
59+
var rectangle badRectangle = badRectangle{Height: height, Width: width}
60+
return &rectangle
61+
}
62+
63+
func (rectangle *badRectangle) GetArea() (float64, error) {
64+
return rectangle.Height * rectangle.Width, nil
65+
}
66+
67+
/* -------------------------------- BadCircle ------------------------------- */
68+
69+
type badCircle struct {
70+
Radius float64
71+
_ struct{}
72+
}
73+
74+
func NewBadCircle(radius float64) BadShape {
75+
var circle badCircle = badCircle{Radius: radius}
76+
return &circle
77+
}
78+
79+
func (circle *badCircle) GetArea() (float64, error) {
80+
return 0, errors.New("Area calculation method of circle is not implemented")
81+
}
82+
83+
/* ------------------------------ GoodRectangle ----------------------------- */
84+
85+
type goodRectangle struct {
86+
Height float64
87+
Width float64
88+
_ struct{}
89+
}
90+
91+
func NewGoodRectangle(height float64, width float64) GoodShape {
92+
var rectangle goodRectangle = goodRectangle{Height: height, Width: width}
93+
return &rectangle
94+
}
95+
96+
func (rectangle *goodRectangle) GetArea() float64 {
97+
return rectangle.Height * rectangle.Width
98+
}
99+
100+
/* ------------------------------- GoodCircle ------------------------------- */
101+
102+
type goodCircle struct {
103+
Radius float64
104+
_ struct{}
105+
}
106+
107+
func NewGoodCircle(radius float64) GoodShape {
108+
var circle goodCircle = goodCircle{Radius: radius}
109+
return &circle
110+
}
111+
112+
func (circle *goodCircle) GetArea() float64 {
113+
return math.Pi * math.Pow(circle.Radius, 2)
114+
}
115+
116+
/* ----------------------------------- Car ---------------------------------- */
117+
118+
type car struct{}
119+
120+
func NewCar() Vehicle {
121+
var car car = car{}
122+
return &car
123+
}
124+
125+
func (car *car) Brake() {
126+
fmt.Println("Car braking!")
127+
}
128+
129+
func (car *car) SpeedUp() {
130+
fmt.Println("Car speeding up!")
131+
}
132+
133+
/* ---------------------------------- Truck --------------------------------- */
134+
135+
type truck struct{}
136+
137+
func NewTruck() Vehicle {
138+
var truck truck = truck{}
139+
return &truck
140+
}
141+
142+
func (truck *truck) Brake() {
143+
fmt.Println("Truck braking!")
144+
}
145+
146+
func (truck *truck) SpeedUp() {
147+
fmt.Println("Truck speeding up!")
148+
}
149+
150+
/* ---------------------------------- Boat ---------------------------------- */
151+
152+
type boat struct{}
153+
154+
func NewBoat() Vehicle {
155+
var boat boat = boat{}
156+
return &boat
157+
}
158+
159+
func (boat *boat) Brake() {
160+
fmt.Println("Boat braking!")
161+
}
162+
163+
func (boat *boat) SpeedUp() {
164+
fmt.Println("Boat speeding up!")
165+
}
166+
167+
/* -------------------------------------------------------------------------- */
168+
/* MAIN */
169+
/* -------------------------------------------------------------------------- */
170+
171+
func main() {
172+
/*
173+
Liskov Substitution Principle (LCP)...
174+
*/
175+
176+
fmt.Println("Liskov Substitution Principle (LCP)...")
177+
178+
fmt.Println("\nBad implementation of Liskov Substitution Principle (LCP)...")
179+
180+
fmt.Println("\n```\n" + `type BadShape interface {
181+
GetArea() (float64, error)
182+
}
183+
184+
func BadGetArea(shape BadShape) (float64, error) {
185+
return shape.GetArea()
186+
}
187+
188+
type badRectangle struct {
189+
Height float64
190+
Width float64
191+
_ struct{}
192+
}
193+
194+
func NewBadRectangle(height float64, width float64) BadShape {
195+
var rectangle badRectangle = badRectangle{Height: height, Width: width}
196+
return &rectangle
197+
}
198+
199+
func (rectangle *badRectangle) GetArea() (float64, error) {
200+
return rectangle.Height * rectangle.Width, nil
201+
}
202+
203+
type badCircle struct {
204+
Radius float64
205+
_ struct{}
206+
}
207+
208+
func NewBadCircle(radius float64) BadShape {
209+
var circle badCircle = badCircle{Radius: radius}
210+
return &circle
211+
}
212+
213+
func (circle *badCircle) GetArea() (float64, error) {
214+
return 0, errors.New("Area calculation method of circle is not implemented")
215+
}` + "\n```")
216+
217+
fmt.Println(
218+
"\nThis is a bad implementation of Liskov Substitution Principle (LCP),\n" +
219+
"because the 'BadGetArea' method of 'badCircle' is no implemented. So, if we\n" +
220+
"execute the 'BadGetArea' function with both classes ('badRectangle', and 'badCircle')\n" +
221+
"the function will produce different side effects that could be break the function execution.\n" +
222+
"Thus the 'BadShape' interface can not be replaced by 'badCircle' class.",
223+
)
224+
225+
fmt.Println("\nGood implementation of Liskov Substitution Principle (LCP)...")
226+
227+
fmt.Println("\n```\n" + `type GoodShape interface {
228+
GetArea() float64
229+
}
230+
231+
func GoodGetArea(shape GoodShape) float64 {
232+
return shape.GetArea()
233+
}
234+
235+
type goodRectangle struct {
236+
Height float64
237+
Width float64
238+
_ struct{}
239+
}
240+
241+
func NewGoodRectangle(height float64, width float64) GoodShape {
242+
var rectangle goodRectangle = goodRectangle{Height: height, Width: width}
243+
return &rectangle
244+
}
245+
246+
func (rectangle *goodRectangle) GetArea() float64 {
247+
return rectangle.Height * rectangle.Width
248+
}
249+
250+
type goodCircle struct {
251+
Radius float64
252+
_ struct{}
253+
}
254+
255+
func NewGoodCircle(radius float64) GoodShape {
256+
var circle goodCircle = goodCircle{Radius: radius}
257+
return &circle
258+
}
259+
260+
func (circle *goodCircle) GetArea() float64 {
261+
return math.Pi * math.Pow(circle.Radius, 2)
262+
}` + "\n```")
263+
264+
fmt.Println(
265+
"\nThis is a good implementation of Liskov Substitution Principle (LCP),\n" +
266+
"because all classes which implements 'GoodShape' interface implements the\n" +
267+
"'GoodGetArea' method with the same side effect. So, if we execute the 'GoodGetArea'\n" +
268+
"function with both classes ('GoodRectangle', and 'GoodCircle'), we are not going to\n" +
269+
"have side effects that could break the function execution. Thus the 'GoodShape' interface\n" +
270+
"can be replaced by any of these classes.",
271+
)
272+
273+
fmt.Println(
274+
"\n# ---------------------------------------------------------------------------------- #",
275+
)
276+
277+
/*
278+
Additional challenge...
279+
*/
280+
281+
fmt.Println("\nAdditional challenge...")
282+
283+
var car Vehicle = NewCar()
284+
var truck Vehicle = NewTruck()
285+
var boat Vehicle = NewBoat()
286+
287+
fmt.Println()
288+
SpeedUp(car)
289+
SpeedUp(truck)
290+
SpeedUp(boat)
291+
292+
fmt.Println()
293+
Brake(car)
294+
Brake(truck)
295+
Brake(boat)
296+
}

0 commit comments

Comments
 (0)