1
+ """
2
+ EJERCICIO:
3
+ Explora el "Principio SOLID de Segregación de Interfaces (Interface
4
+ Segregation Principle, ISP)" y crea un ejemplo simple donde se
5
+ muestre su funcionamiento de forma correcta e incorrecta.
6
+
7
+ DIFICULTAD EXTRA(opcional):
8
+ Crea un gestor de impresoras.
9
+
10
+ Requisitos:
11
+ 1. Algunas impresoras sólo imprimen en blanco y negro.
12
+ 2. Otras sólo a color.
13
+ 3. Otras son multifunción, pueden imprimir, escanear y enviar fax.
14
+ Instrucciones:
15
+ 1. Implementa el sistema, con los diferentes tipos de impresoras y funciones.
16
+ 2. Aplica el ISP a la implementación.
17
+ 3. Desarrolla un código que compruebe que se cumple el principio.
18
+
19
+ by adra-dev
20
+ """
21
+
22
+ """
23
+ Interface Segregation Principle (ISP):
24
+ El Principio de Segregación de Interfaces también fue propuesto por
25
+ uncle bob. la idea central del principio es:
26
+
27
+ "Los clientes no deberían ser forzados a depender de métodos que
28
+ ellos no usan. las interfaces pertenecen a los clientes no a sus
29
+ herencias."
30
+
31
+ documentacion:"https://realpython.com/solid-principles-python/"
32
+
33
+ En este caso, los clientes son las clases y las subclases y las
34
+ interfaces consisten en los métodos y atributos. En otras palabras,
35
+ si una clase utiliza métodos en particular o atributos entonces esos
36
+ métodos y atributos deberían ser segregados a clases más específicas.
37
+
38
+ Considera el siguiente ejemplo.
39
+ """
40
+
41
+ # printers_isp.py
42
+
43
+ from abc import ABC , abstractmethod
44
+
45
+ class Printer (ABC ):
46
+ @abstractmethod
47
+ def print (self , document ):
48
+ pass
49
+
50
+ @abstractmethod
51
+ def fax (self , document ):
52
+ pass
53
+
54
+ @abstractmethod
55
+ def scan (self , document ):
56
+ pass
57
+
58
+ class OldPrinter (Printer ):
59
+ def print (self , document ):
60
+ print (f"Printing { document } in black and white..." )
61
+
62
+ def fax (self , document ):
63
+ raise NotImplementedError ("Fax functionality not supported" )
64
+
65
+ def scan (self , document ):
66
+ raise NotImplementedError ("Scan functionality not supported" )
67
+
68
+ class ModernPrinter (Printer ):
69
+ def print (self , document ):
70
+ print (f"Printing { document } in color..." )
71
+
72
+ def fax (self , document ):
73
+ print (f"Faxing { document } ..." )
74
+
75
+ def scan (self , document ):
76
+ print (f"Scanning { document } ..." )
77
+
78
+ """
79
+ En este ejemplo, la clase base, impresora, provee las interfaces que
80
+ sus subclases deben implementar. OldPrinter hereda de printer y debe
81
+ implementar la misma interfaz. Sin embargo, OldPrinter no utiliza los
82
+ métodos .fax() y .scan() porque este tipo de impresora no soporta
83
+ estas funcionalidades.
84
+
85
+ Esta implementación viola el ISP porque obliga a OldPrinter a mostrar
86
+ una interfaz que la subclase no implementa o necesita. Para
87
+ solucionar este problema, deberías separar las interfaces en clases
88
+ más pequeñas y más específicas. Así después puedes crear subclases
89
+ más concretas por medio de la herencia de múltiples interfaces que
90
+ dicha subclase necesite.
91
+
92
+ """
93
+
94
+ # printers_isp.py
95
+
96
+ from abc import ABC , abstractmethod
97
+
98
+ class Printer (ABC ):
99
+ @abstractmethod
100
+ def print (self , document ):
101
+ pass
102
+
103
+ class Fax (ABC ):
104
+ @abstractmethod
105
+ def fax (self , document ):
106
+ pass
107
+
108
+ class Scanner (ABC ):
109
+ @abstractmethod
110
+ def scan (self , document ):
111
+ pass
112
+
113
+ class OldPrinter (Printer ):
114
+ def print (self , document ):
115
+ print (f"Printing { document } in black and white..." )
116
+
117
+ class NewPrinter (Printer , Fax , Scanner ):
118
+ def print (self , document ):
119
+ print (f"Printing { document } in color..." )
120
+
121
+ def fax (self , document ):
122
+ print (f"Faxing { document } ..." )
123
+
124
+ def scan (self , document ):
125
+ print (f"Scanning { document } ..." )
126
+
127
+ """
128
+
129
+ Ahora Printer, Fax y Scanner son clases base que proveen interfaces
130
+ específicas con una única responsabilidad cada una. Para crear
131
+ OldPrinter, ya solo necesitas heredar la interfaz de Printer. De este
132
+ modo, la clase no tendrá métodos que no se utilicen. Para crear la
133
+ clase ModernPrinter, solo necesitas heredar de todas las interfaces
134
+ en resumen haz segregado la interfaz de Printer.
135
+
136
+ """
137
+
138
+ """
139
+ Extra
140
+ """
141
+
142
+ from abc import ABC , abstractmethod
143
+
144
+ class Printer (ABC ):
145
+ @abstractmethod
146
+ def print (self , document ):
147
+ pass
148
+
149
+ class Fax (ABC ):
150
+ @abstractmethod
151
+ def fax (self , document ):
152
+ pass
153
+
154
+ class Scanner (ABC ):
155
+ @abstractmethod
156
+ def scan (self , document ):
157
+ pass
158
+
159
+
160
+ class BlackWhitePrinter (Printer ):
161
+ def print (self , document ):
162
+ print (f"Printing { document } in black and white..." )
163
+
164
+
165
+ class ColorPrinter (Printer ):
166
+ def print (self , document ):
167
+ print (f"Printing { document } in color..." )
168
+
169
+
170
+ class LastModelPrinter (Printer , Fax , Scanner ):
171
+ def print (self , document ):
172
+ print (f"Printing { document } in black and white..." )
173
+
174
+ def print_color (self , document ):
175
+ print (f"Printing { document } in color..." )
176
+
177
+ def fax (self , document ):
178
+ print (f"Faxing { document } ..." )
179
+
180
+ def scan (self , document ):
181
+ print (f"Scanning { document } ..." )
182
+
183
+
184
+ def test_printers ():
185
+
186
+ printer = BlackWhitePrinter ()
187
+ color_printer = ColorPrinter ()
188
+ multifunction_printer = LastModelPrinter ()
189
+
190
+ printer .print ("doc.pdf" )
191
+ color_printer .print ("doc.pdf" )
192
+ multifunction_printer .print ("doc.pdf" )
193
+ multifunction_printer .print_color ("doc.pdf" )
194
+ multifunction_printer .scan ("doc.pdf" )
195
+ multifunction_printer .fax ("doc.pdf" )
196
+
197
+
198
+ test_printers ()
0 commit comments