@icarusmx/creta 0.9.0 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lessons/lesson6-interface-design.js +220 -132
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// LECCIÓN 6: El énfasis al diseñar los objetos debe estar en la definición de sus solicitudes e interfaces
|
|
4
|
-
// Enfoque práctico: Sistema
|
|
4
|
+
// Enfoque práctico: Sistema bancario con diseño interface-first y encapsulación
|
|
5
5
|
|
|
6
6
|
import { createInterface } from 'readline'
|
|
7
7
|
|
|
@@ -33,13 +33,13 @@ export class Lesson6InterfaceDesign {
|
|
|
33
33
|
|
|
34
34
|
async practicalExercise() {
|
|
35
35
|
console.clear()
|
|
36
|
-
console.log("🛠️ EJERCICIO PRÁCTICO: Sistema
|
|
36
|
+
console.log("🛠️ EJERCICIO PRÁCTICO: Sistema Bancario")
|
|
37
37
|
console.log("=" .repeat(50))
|
|
38
38
|
console.log("🎯 Objetivo: Diseñar interfaces ANTES de implementar")
|
|
39
|
-
console.log("\nVamos a crear un sistema donde:")
|
|
40
|
-
console.log("-
|
|
41
|
-
console.log("-
|
|
42
|
-
console.log("-
|
|
39
|
+
console.log("\nVamos a crear un sistema bancario donde:")
|
|
40
|
+
console.log("- BankAccount representa una cuenta con balance privado")
|
|
41
|
+
console.log("- Transaction registra movimientos entre cuentas")
|
|
42
|
+
console.log("- Bank gestiona múltiples cuentas y validaciones")
|
|
43
43
|
|
|
44
44
|
await this.waitForEnter("\nPresiona Enter para ver cómo diseñar las interfaces...")
|
|
45
45
|
|
|
@@ -54,21 +54,22 @@ export class Lesson6InterfaceDesign {
|
|
|
54
54
|
console.log("📋 PASO 1: Definir las Solicitudes")
|
|
55
55
|
console.log("=" .repeat(40))
|
|
56
56
|
console.log("Antes de escribir código, pensemos: ¿Qué solicitudes debe manejar cada objeto?")
|
|
57
|
-
console.log("\n
|
|
58
|
-
console.log(" -
|
|
59
|
-
console.log(" -
|
|
60
|
-
console.log(" -
|
|
61
|
-
console.log(" -
|
|
62
|
-
|
|
63
|
-
console.log("\n
|
|
64
|
-
console.log(" -
|
|
65
|
-
console.log(" -
|
|
66
|
-
console.log(" - Validar si
|
|
67
|
-
|
|
68
|
-
console.log("\n
|
|
69
|
-
console.log(" -
|
|
70
|
-
console.log(" -
|
|
71
|
-
console.log(" -
|
|
57
|
+
console.log("\n🏦 BankAccount debe poder:")
|
|
58
|
+
console.log(" - Consultar balance (sin exponer el dato interno)")
|
|
59
|
+
console.log(" - Recibir dinero (depósito)")
|
|
60
|
+
console.log(" - Enviar dinero (con validación interna)")
|
|
61
|
+
console.log(" - Proporcionar información de la cuenta")
|
|
62
|
+
|
|
63
|
+
console.log("\n📊 Transaction debe poder:")
|
|
64
|
+
console.log(" - Registrar origen, destino y monto")
|
|
65
|
+
console.log(" - Proporcionar detalles del movimiento")
|
|
66
|
+
console.log(" - Validar si la transacción es válida")
|
|
67
|
+
|
|
68
|
+
console.log("\n🏛️ Bank debe poder:")
|
|
69
|
+
console.log(" - Crear nuevas cuentas")
|
|
70
|
+
console.log(" - Procesar transferencias entre cuentas")
|
|
71
|
+
console.log(" - Validar operaciones antes de ejecutarlas")
|
|
72
|
+
console.log(" - Llevar registro de todas las transacciones")
|
|
72
73
|
|
|
73
74
|
await this.waitForEnter("\n✅ ¡Excelente! Ya definimos QUÉ debe hacer cada objeto. Presiona Enter para definir las interfaces...")
|
|
74
75
|
}
|
|
@@ -79,33 +80,36 @@ export class Lesson6InterfaceDesign {
|
|
|
79
80
|
console.log("=" .repeat(50))
|
|
80
81
|
console.log("Ahora especifiquemos CÓMO se solicitan estas operaciones:")
|
|
81
82
|
|
|
82
|
-
console.log("\n//
|
|
83
|
-
console.log("class
|
|
84
|
-
console.log("
|
|
85
|
-
console.log("
|
|
86
|
-
console.log("
|
|
87
|
-
console.log("
|
|
83
|
+
console.log("\n// BankAccount Interface")
|
|
84
|
+
console.log("class BankAccount {")
|
|
85
|
+
console.log(" constructor(accountNumber, ownerName, initialBalance) → BankAccount")
|
|
86
|
+
console.log(" getBalance() → number // ⚠️ ENCAPSULACIÓN: acceso controlado")
|
|
87
|
+
console.log(" getAccountInfo() → {number, owner, balance}")
|
|
88
|
+
console.log(" deposit(amount) → boolean")
|
|
89
|
+
console.log(" send(amount, targetAccount) → boolean // ⚠️ VALIDACIÓN interna")
|
|
88
90
|
console.log("}")
|
|
89
91
|
|
|
90
|
-
console.log("\n//
|
|
91
|
-
console.log("class
|
|
92
|
-
console.log(" constructor(
|
|
93
|
-
console.log("
|
|
94
|
-
console.log("
|
|
95
|
-
console.log(" isCompleted() → boolean")
|
|
92
|
+
console.log("\n// Transaction Interface")
|
|
93
|
+
console.log("class Transaction {")
|
|
94
|
+
console.log(" constructor(from, to, amount, timestamp) → Transaction")
|
|
95
|
+
console.log(" getDetails() → {from, to, amount, timestamp, status}")
|
|
96
|
+
console.log(" isValid() → boolean")
|
|
96
97
|
console.log("}")
|
|
97
98
|
|
|
98
|
-
console.log("\n//
|
|
99
|
-
console.log("class
|
|
100
|
-
console.log("
|
|
101
|
-
console.log("
|
|
102
|
-
console.log("
|
|
99
|
+
console.log("\n// Bank Interface")
|
|
100
|
+
console.log("class Bank {")
|
|
101
|
+
console.log(" createAccount(ownerName, initialBalance) → BankAccount")
|
|
102
|
+
console.log(" transfer(fromAccount, toAccount, amount) → Transaction")
|
|
103
|
+
console.log(" getAllTransactions() → Array<Transaction>")
|
|
104
|
+
console.log(" validateOperation(account, amount) → boolean")
|
|
103
105
|
console.log("}")
|
|
104
106
|
|
|
105
107
|
console.log("\n💡 Observa que cada operación especifica:")
|
|
106
|
-
console.log(" a) Nombre de la operación (
|
|
107
|
-
console.log(" b) Insumos necesarios (
|
|
108
|
-
console.log(" c) Valor que regresa (
|
|
108
|
+
console.log(" a) Nombre de la operación (getBalance, send, transfer, etc.)")
|
|
109
|
+
console.log(" b) Insumos necesarios (amount, targetAccount, etc.)")
|
|
110
|
+
console.log(" c) Valor que regresa (boolean, Transaction, etc.)")
|
|
111
|
+
console.log("\n🔒 Nota especial: getBalance() encapsula el acceso al estado interno")
|
|
112
|
+
console.log("🛡️ Nota especial: send() incluirá validación antes de ejecutar")
|
|
109
113
|
|
|
110
114
|
await this.waitForEnter("\n✅ Interfaces definidas. Presiona Enter para implementar...")
|
|
111
115
|
}
|
|
@@ -116,90 +120,126 @@ export class Lesson6InterfaceDesign {
|
|
|
116
120
|
console.log("=" .repeat(40))
|
|
117
121
|
console.log("Ahora que tenemos las interfaces claras, implementemos:")
|
|
118
122
|
|
|
119
|
-
console.log("\n// Implementación de
|
|
120
|
-
console.log(`class
|
|
121
|
-
constructor(
|
|
122
|
-
this.
|
|
123
|
-
this.
|
|
124
|
-
this
|
|
125
|
-
this.completed = false
|
|
123
|
+
console.log("\n// Implementación de BankAccount")
|
|
124
|
+
console.log(`class BankAccount {
|
|
125
|
+
constructor(accountNumber, ownerName, initialBalance) {
|
|
126
|
+
this.accountNumber = accountNumber
|
|
127
|
+
this.ownerName = ownerName
|
|
128
|
+
this.#balance = initialBalance // 🔒 PRIVADO: no se accede directamente
|
|
126
129
|
}
|
|
127
130
|
|
|
128
|
-
|
|
131
|
+
// 🔑 ENCAPSULACIÓN: método GET para acceder al balance
|
|
132
|
+
getBalance() {
|
|
133
|
+
return this.#balance
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getAccountInfo() {
|
|
129
137
|
return {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
completed: this.completed
|
|
138
|
+
number: this.accountNumber,
|
|
139
|
+
owner: this.ownerName,
|
|
140
|
+
balance: this.#balance // Controlamos qué se expone
|
|
134
141
|
}
|
|
135
142
|
}
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
deposit(amount) {
|
|
145
|
+
if (amount > 0) {
|
|
146
|
+
this.#balance += amount
|
|
147
|
+
return true
|
|
148
|
+
}
|
|
149
|
+
return false
|
|
139
150
|
}
|
|
140
151
|
|
|
141
|
-
|
|
142
|
-
|
|
152
|
+
// 🛡️ VALIDACIÓN: método SEND con lógica interna
|
|
153
|
+
send(amount, targetAccount) {
|
|
154
|
+
// Validación interna ANTES de ejecutar
|
|
155
|
+
if (amount > 0 && this.#balance >= amount) {
|
|
156
|
+
this.#balance -= amount
|
|
157
|
+
targetAccount.deposit(amount)
|
|
158
|
+
return true
|
|
159
|
+
}
|
|
160
|
+
return false // Fondos insuficientes o monto inválido
|
|
143
161
|
}
|
|
144
162
|
}`)
|
|
145
163
|
|
|
146
|
-
await this.waitForEnter("\nPresiona Enter para ver
|
|
164
|
+
await this.waitForEnter("\nPresiona Enter para ver Transaction...")
|
|
147
165
|
|
|
148
|
-
console.log("\n// Implementación de
|
|
149
|
-
console.log(`class
|
|
150
|
-
constructor() {
|
|
151
|
-
this.
|
|
166
|
+
console.log("\n// Implementación de Transaction")
|
|
167
|
+
console.log(`class Transaction {
|
|
168
|
+
constructor(fromAccount, toAccount, amount) {
|
|
169
|
+
this.fromAccount = fromAccount
|
|
170
|
+
this.toAccount = toAccount
|
|
171
|
+
this.amount = amount
|
|
172
|
+
this.timestamp = new Date()
|
|
173
|
+
this.status = 'pending'
|
|
152
174
|
}
|
|
153
175
|
|
|
154
|
-
|
|
155
|
-
|
|
176
|
+
getDetails() {
|
|
177
|
+
return {
|
|
178
|
+
from: this.fromAccount.accountNumber,
|
|
179
|
+
to: this.toAccount.accountNumber,
|
|
180
|
+
amount: this.amount,
|
|
181
|
+
timestamp: this.timestamp,
|
|
182
|
+
status: this.status
|
|
183
|
+
}
|
|
156
184
|
}
|
|
157
185
|
|
|
158
|
-
|
|
159
|
-
return
|
|
186
|
+
isValid() {
|
|
187
|
+
return this.amount > 0 &&
|
|
188
|
+
this.fromAccount.getBalance() >= this.amount
|
|
160
189
|
}
|
|
161
190
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
this.
|
|
166
|
-
return
|
|
191
|
+
execute() {
|
|
192
|
+
if (this.isValid()) {
|
|
193
|
+
const success = this.fromAccount.send(this.amount, this.toAccount)
|
|
194
|
+
this.status = success ? 'completed' : 'failed'
|
|
195
|
+
return success
|
|
167
196
|
}
|
|
197
|
+
this.status = 'failed'
|
|
168
198
|
return false
|
|
169
199
|
}
|
|
170
200
|
}`)
|
|
171
201
|
|
|
172
|
-
await this.waitForEnter("\nPresiona Enter para ver
|
|
202
|
+
await this.waitForEnter("\nPresiona Enter para ver Bank...")
|
|
173
203
|
|
|
174
|
-
console.log("\n// Implementación de
|
|
175
|
-
console.log(`class
|
|
176
|
-
constructor(
|
|
177
|
-
this.
|
|
178
|
-
this.
|
|
204
|
+
console.log("\n// Implementación de Bank")
|
|
205
|
+
console.log(`class Bank {
|
|
206
|
+
constructor() {
|
|
207
|
+
this.accounts = []
|
|
208
|
+
this.transactions = []
|
|
209
|
+
this.nextAccountNumber = 1000
|
|
179
210
|
}
|
|
180
211
|
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
212
|
+
createAccount(ownerName, initialBalance) {
|
|
213
|
+
const account = new BankAccount(
|
|
214
|
+
this.nextAccountNumber++,
|
|
215
|
+
ownerName,
|
|
216
|
+
initialBalance
|
|
217
|
+
)
|
|
218
|
+
this.accounts.push(account)
|
|
219
|
+
return account
|
|
185
220
|
}
|
|
186
221
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
222
|
+
transfer(fromAccount, toAccount, amount) {
|
|
223
|
+
const transaction = new Transaction(fromAccount, toAccount, amount)
|
|
190
224
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return true
|
|
225
|
+
// El Bank valida ANTES de ejecutar
|
|
226
|
+
if (this.validateOperation(fromAccount, amount)) {
|
|
227
|
+
const success = transaction.execute()
|
|
228
|
+
this.transactions.push(transaction)
|
|
229
|
+
return transaction
|
|
197
230
|
}
|
|
198
|
-
|
|
231
|
+
|
|
232
|
+
transaction.status = 'failed'
|
|
233
|
+
this.transactions.push(transaction)
|
|
234
|
+
return transaction
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
validateOperation(account, amount) {
|
|
238
|
+
return amount > 0 && account.getBalance() >= amount
|
|
199
239
|
}
|
|
200
240
|
|
|
201
|
-
|
|
202
|
-
return this.
|
|
241
|
+
getAllTransactions() {
|
|
242
|
+
return [...this.transactions]
|
|
203
243
|
}
|
|
204
244
|
}`)
|
|
205
245
|
|
|
@@ -212,62 +252,102 @@ export class Lesson6InterfaceDesign {
|
|
|
212
252
|
console.log("=" .repeat(45))
|
|
213
253
|
console.log("Veamos cómo los objetos colaboran usando sus interfaces:")
|
|
214
254
|
|
|
215
|
-
console.log("\n// Crear el sistema")
|
|
216
|
-
console.log("const
|
|
217
|
-
console.log("const
|
|
255
|
+
console.log("\n// Crear el sistema bancario")
|
|
256
|
+
console.log("const bank = new Bank()")
|
|
257
|
+
console.log("const cuenta1 = bank.createAccount('Ana García', 1000)")
|
|
258
|
+
console.log("const cuenta2 = bank.createAccount('Carlos López', 500)")
|
|
218
259
|
console.log("")
|
|
219
|
-
console.log("//
|
|
220
|
-
console.log("
|
|
221
|
-
console.log("
|
|
260
|
+
console.log("// 🔑 ENCAPSULACIÓN: Solo podemos acceder al balance via getBalance()")
|
|
261
|
+
console.log("console.log('Balance Ana:', cuenta1.getBalance()) // 1000")
|
|
262
|
+
console.log("console.log('Balance Carlos:', cuenta2.getBalance()) // 500")
|
|
222
263
|
console.log("")
|
|
223
|
-
console.log("//
|
|
224
|
-
console.log("
|
|
225
|
-
console.log("
|
|
264
|
+
console.log("// 🛡️ VALIDACIÓN: send() verifica internamente antes de ejecutar")
|
|
265
|
+
console.log("const exitoso = cuenta1.send(300, cuenta2) // ✅ Tiene fondos")
|
|
266
|
+
console.log("console.log('Transferencia exitosa:', exitoso) // true")
|
|
226
267
|
console.log("")
|
|
227
|
-
console.log("
|
|
228
|
-
console.log("
|
|
229
|
-
console.log("
|
|
230
|
-
console.log("
|
|
268
|
+
console.log("const fallido = cuenta1.send(1500, cuenta2) // ❌ Fondos insuficientes")
|
|
269
|
+
console.log("console.log('Transferencia fallida:', fallido) // false")
|
|
270
|
+
console.log("")
|
|
271
|
+
console.log("// El estado interno se mantiene íntegro")
|
|
272
|
+
console.log("console.log('Balance final Ana:', cuenta1.getBalance()) // 700")
|
|
273
|
+
console.log("console.log('Balance final Carlos:', cuenta2.getBalance()) // 800")
|
|
231
274
|
|
|
232
275
|
console.log("\n🎯 Resultado esperado:")
|
|
233
|
-
console.log("
|
|
234
|
-
console.log("
|
|
276
|
+
console.log("Balance Ana: 1000")
|
|
277
|
+
console.log("Balance Carlos: 500")
|
|
278
|
+
console.log("Transferencia exitosa: true")
|
|
279
|
+
console.log("Transferencia fallida: false")
|
|
280
|
+
console.log("Balance final Ana: 700")
|
|
281
|
+
console.log("Balance final Carlos: 800")
|
|
235
282
|
|
|
236
283
|
await this.waitForEnter("\nPresiona Enter para ver los beneficios de este enfoque...")
|
|
237
284
|
|
|
238
285
|
console.clear()
|
|
239
|
-
console.log("🌟 BENEFICIOS DEL DISEÑO INTERFACE-FIRST")
|
|
240
|
-
console.log("=" .repeat(
|
|
241
|
-
console.log("1.
|
|
242
|
-
console.log("2.
|
|
243
|
-
console.log("3.
|
|
244
|
-
console.log("4.
|
|
245
|
-
console.log("5.
|
|
286
|
+
console.log("🌟 BENEFICIOS DEL DISEÑO INTERFACE-FIRST EN SISTEMAS BANCARIOS")
|
|
287
|
+
console.log("=" .repeat(60))
|
|
288
|
+
console.log("1. 🔒 Encapsulación: El balance está protegido, solo accesible via getBalance()")
|
|
289
|
+
console.log("2. 🛡️ Validación: send() incluye lógica de negocio interna")
|
|
290
|
+
console.log("3. 🎯 Claridad: Cada objeto tiene responsabilidades financieras bien definidas")
|
|
291
|
+
console.log("4. 🔗 Colaboración: Los objetos saben exactamente cómo solicitar operaciones")
|
|
292
|
+
console.log("5. 🧪 Testeable: Podemos simular cuentas y transacciones fácilmente")
|
|
293
|
+
console.log("6. 📚 Mantenible: Las interfaces documentan el contrato bancario")
|
|
246
294
|
|
|
247
295
|
console.log("\n💡 Ejemplo de extensibilidad:")
|
|
248
|
-
console.log("// Podemos
|
|
249
|
-
console.log("class
|
|
250
|
-
console.log("
|
|
251
|
-
console.log("
|
|
252
|
-
console.log("
|
|
296
|
+
console.log("// Podemos crear diferentes tipos de cuenta sin cambiar Bank")
|
|
297
|
+
console.log("class SavingsAccount extends BankAccount {")
|
|
298
|
+
console.log(" getBalance() {")
|
|
299
|
+
console.log(" return super.getBalance() + this.calculateInterest()")
|
|
300
|
+
console.log(" }")
|
|
301
|
+
console.log("}")
|
|
302
|
+
console.log("")
|
|
303
|
+
console.log("class CreditAccount extends BankAccount {")
|
|
304
|
+
console.log(" send(amount, target) {")
|
|
305
|
+
console.log(" // Permite sobregiro hasta el límite de crédito")
|
|
306
|
+
console.log(" if (amount > 0 && (this.getBalance() + this.creditLimit) >= amount) {")
|
|
307
|
+
console.log(" // ... lógica específica")
|
|
308
|
+
console.log(" }")
|
|
309
|
+
console.log(" }")
|
|
253
310
|
console.log("}")
|
|
254
311
|
console.log("")
|
|
255
|
-
console.log("//
|
|
256
|
-
console.log("const
|
|
257
|
-
console.log("const
|
|
312
|
+
console.log("// Las cuentas pueden enviarse dinero directamente!")
|
|
313
|
+
console.log("const savingsAcc = new SavingsAccount(123, 'María', 1000)")
|
|
314
|
+
console.log("const creditAcc = new CreditAccount(456, 'Juan', 500, 2000) // límite crédito")
|
|
315
|
+
console.log("savingsAcc.send(300, creditAcc) // ¡Funciona con cualquier tipo de cuenta!")
|
|
316
|
+
console.log("")
|
|
317
|
+
console.log("// O podemos usar el Bank para registro completo:")
|
|
318
|
+
console.log("bank.transfer(savingsAcc, creditAcc, 300) // Crea Transaction automáticamente")
|
|
258
319
|
|
|
259
320
|
await this.waitForEnter("\nPresiona Enter para continuar con la conclusión...")
|
|
260
321
|
}
|
|
261
322
|
|
|
262
323
|
async conclusion() {
|
|
263
324
|
console.clear()
|
|
264
|
-
console.log("🎓 CONCLUSIÓN: Diseño basado en Interfaces")
|
|
265
|
-
console.log("=" .repeat(
|
|
325
|
+
console.log("🎓 CONCLUSIÓN: Diseño basado en Interfaces (Sistema Bancario)")
|
|
326
|
+
console.log("=" .repeat(55))
|
|
266
327
|
console.log("🎯 Hemos demostrado que:")
|
|
267
328
|
console.log("\n1. El ÉNFASIS debe estar en definir QUÉ solicitudes maneja cada objeto")
|
|
268
|
-
console.log("2. Las INTERFACES
|
|
269
|
-
console.log("3.
|
|
270
|
-
console.log("4.
|
|
329
|
+
console.log("2. Las INTERFACES son el CONJUNTO de todas las firmas de operación")
|
|
330
|
+
console.log("3. Cada FIRMA especifica: nombre, insumos y valor de retorno")
|
|
331
|
+
console.log("4. La IMPLEMENTACIÓN viene después, siguiendo el contrato")
|
|
332
|
+
console.log("5. Los objetos COLABORAN a través de estas interfaces bien definidas")
|
|
333
|
+
|
|
334
|
+
console.log("\n📋 Firmas de operación en nuestro ejemplo:")
|
|
335
|
+
console.log("• BankAccount.getBalance() → number")
|
|
336
|
+
console.log("• BankAccount.send(amount, targetAccount) → boolean")
|
|
337
|
+
console.log("• Bank.createAccount(ownerName, initialBalance) → BankAccount")
|
|
338
|
+
console.log("• Bank.transfer(fromAccount, toAccount, amount) → Transaction")
|
|
339
|
+
console.log("• Transaction.getDetails() → {from, to, amount, timestamp, status}")
|
|
340
|
+
|
|
341
|
+
console.log("\n🔑 La interfaz de BankAccount es el CONJUNTO completo:")
|
|
342
|
+
console.log(" {getBalance, getAccountInfo, deposit, send}")
|
|
343
|
+
console.log("🔑 La interfaz de Bank es el CONJUNTO completo:")
|
|
344
|
+
console.log(" {createAccount, transfer, getAllTransactions, validateOperation}")
|
|
345
|
+
|
|
346
|
+
console.log("\n💡 Beneficios de este enfoque:")
|
|
347
|
+
console.log("• ENCAPSULACIÓN: getBalance() protege el acceso al estado interno")
|
|
348
|
+
console.log("• VALIDACIÓN: send() ejecuta lógica de negocio antes de operar")
|
|
349
|
+
console.log("• CONTRATO CLARO: Cada firma especifica exactamente qué esperar")
|
|
350
|
+
console.log("• COLABORACIÓN: Los objetos conocen las firmas de otros objetos")
|
|
271
351
|
|
|
272
352
|
console.log("\n📚 Conexión con lecciones anteriores:")
|
|
273
353
|
console.log("• Lección 2: Los objetos interactúan a través de solicitudes ✓")
|
|
@@ -280,12 +360,20 @@ export class Lesson6InterfaceDesign {
|
|
|
280
360
|
console.log("Practica este enfoque en tus propios proyectos:")
|
|
281
361
|
console.log("1. Define primero QUÉ debe hacer cada objeto")
|
|
282
362
|
console.log("2. Especifica las interfaces (firmas de operación)")
|
|
283
|
-
console.log("3.
|
|
284
|
-
console.log("4.
|
|
363
|
+
console.log("3. Incluye validaciones internas en tus métodos")
|
|
364
|
+
console.log("4. Encapsula el estado, expón solo lo necesario")
|
|
365
|
+
console.log("5. Haz que los objetos colaboren a través de solicitudes")
|
|
285
366
|
|
|
286
367
|
console.log("\n💭 Reflexión final:")
|
|
287
|
-
console.log("
|
|
288
|
-
console.log("
|
|
368
|
+
console.log("Antes de implementar cualquier objeto, pregúntate:")
|
|
369
|
+
console.log("• ¿Cuáles son TODAS las firmas de operación que necesito?")
|
|
370
|
+
console.log("• ¿Qué nombre, insumos y valor de retorno tendrá cada firma?")
|
|
371
|
+
console.log("• ¿Cómo van a colaborar los objetos usando estas firmas?")
|
|
372
|
+
console.log("• ¿El CONJUNTO de firmas forma una interfaz coherente?")
|
|
373
|
+
|
|
374
|
+
console.log("\n🏆 ¡Has completado el ejemplo más importante del diseño orientado a objetos!")
|
|
375
|
+
console.log("Ahora entiendes que el ÉNFASIS debe estar en definir el CONJUNTO")
|
|
376
|
+
console.log("completo de firmas de operación ANTES de implementar.")
|
|
289
377
|
|
|
290
378
|
await this.waitForEnter("\n✨ ¡Lección 6 completada! Presiona Enter para salir...")
|
|
291
379
|
}
|