@icarusmx/creta 1.3.3 → 1.3.5

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.
Files changed (39) hide show
  1. package/bin/creta.js +8 -1576
  2. package/codex-refactor.txt +13 -0
  3. package/lib/builders/LessonBuilder.js +228 -0
  4. package/lib/builders/MenuBuilder.js +154 -0
  5. package/lib/builders/ProjectBuilder.js +56 -0
  6. package/lib/cli/index.js +81 -0
  7. package/lib/commands/help.js +5 -0
  8. package/lib/constants/paths.js +9 -0
  9. package/lib/data/enunciados.js +44 -0
  10. package/lib/data/lessons/index.js +25 -0
  11. package/lib/data/lessons/lesson1-system-decomposition.js +312 -0
  12. package/lib/data/lessons/lesson2-object-requests.js +318 -0
  13. package/lib/data/lessons/lesson3-only-way.js +349 -0
  14. package/lib/data/lessons/lesson4-operation-signatures.js +332 -0
  15. package/lib/data/lessons/lesson5-interface-set.js +341 -0
  16. package/lib/data/lessons/lesson6-interface-design.js +407 -0
  17. package/lib/data/lessons/lesson7-object-definition.js +375 -0
  18. package/lib/data/lessons/sintaxis/terminal-basico.js +46 -0
  19. package/lib/data/menus.js +43 -0
  20. package/lib/data/messages.js +28 -0
  21. package/lib/executors/enunciados-executor.js +63 -0
  22. package/lib/executors/portfolio-executor.js +167 -0
  23. package/lib/executors/proyectos-executor.js +23 -0
  24. package/lib/executors/sintaxis-executor.js +7 -0
  25. package/lib/pr-tutorial.js +6 -0
  26. package/lib/templates/LevelModifier.js +287 -0
  27. package/lib/utils/file-utils.js +18 -0
  28. package/lib/utils/input.js +15 -0
  29. package/lib/utils/output.js +4 -0
  30. package/package.json +4 -1
  31. package/refactor.txt +581 -0
  32. package/test/enunciados.test.js +72 -0
  33. package/lessons/lesson1-system-decomposition.js +0 -313
  34. package/lessons/lesson2-object-requests.js +0 -309
  35. package/lessons/lesson3-only-way.js +0 -324
  36. package/lessons/lesson4-operation-signatures.js +0 -319
  37. package/lessons/lesson5-interface-set.js +0 -326
  38. package/lessons/lesson6-interface-design.js +0 -391
  39. package/lessons/lesson7-object-definition.js +0 -300
@@ -1,313 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // LECCIÓN 1: La parte difícil del diseño orientado a objetos es descomponer un sistema como un conjunto de objetos que interactúan entre sí
4
- // Enfoque práctico: Dos definiciones de sistema y su descomposición en objetos
5
-
6
- import { createInterface } from 'readline'
7
-
8
- export class Lesson1SystemDecomposition {
9
- constructor() {
10
- this.rl = createInterface({
11
- input: process.stdin,
12
- output: process.stdout
13
- })
14
- }
15
-
16
- async start() {
17
- await this.waitForEnter("\nPresiona Enter para comenzar...")
18
-
19
- await this.practicalExercise()
20
- await this.conclusion()
21
-
22
- this.rl.close()
23
- }
24
-
25
- async practicalExercise() {
26
- console.clear()
27
- console.log("Comenzaremos con dos definiciones de sistema y posteriormente")
28
- console.log("ejemplificaremos la descomposición en objetos.")
29
-
30
- await this.waitForEnter("\nPresiona Enter para continuar...")
31
-
32
- await this.step1_SystemDefinitions()
33
- await this.step2_ApplyDefinitions()
34
- await this.step3_ObjectIdentification()
35
- }
36
-
37
- async step1_SystemDefinitions() {
38
- console.clear()
39
- console.log("Definición 1:")
40
- console.log("El sistema es una totalidad deductiva de discurso")
41
-
42
- console.log("\nDefinición 2:")
43
- console.log("El sistema es un conjunto de cosas que relacionadas")
44
- console.log("entre sí ordenadamente contribuyen a un determinado propósito")
45
-
46
- await this.waitForEnter("\nPresiona Enter para ver un ejemplo de sistema...")
47
- }
48
-
49
- async step2_ApplyDefinitions() {
50
- console.clear()
51
- console.log("🏛️ Ejemplo: Biblioteca Digital")
52
- console.log("=" .repeat(40))
53
-
54
- console.log("\n📚 Definición 1 - Totalidad deductiva de discurso:")
55
- console.log("Partiendo de 'Biblioteca Digital', ¿qué se deduce naturalmente?")
56
- await this.waitForEnter("\nPresiona Enter para ver la primera deducción...")
57
-
58
- console.log("\n🔍 Primera deducción:")
59
- console.log("• De 'Biblioteca' → contiene LIBROS")
60
- console.log("• De 'Digital' → acceso remoto por USUARIOS")
61
-
62
- await this.waitForEnter("\nPresiona Enter para ver la deducción clave...")
63
-
64
- console.log("\n⚡ Deducción clave:")
65
- console.log("• Libros + Usuarios → deben interactuar")
66
- console.log("• ¿Cómo? → préstamos, búsquedas, devoluciones")
67
- console.log("\n💡 Conclusión: De 'biblioteca digital' se deduce naturalmente")
68
- console.log(" un conjunto de libros y usuarios interactuando")
69
-
70
- await this.waitForEnter("\nPresiona Enter para la segunda definición...")
71
-
72
- console.clear()
73
- console.log("🎯 Definición 2 - Conjunto de cosas con propósito:")
74
- console.log("¿Qué elementos relacionados contribuyen al propósito?")
75
-
76
- console.log("\n📖 Elementos del sistema:")
77
- console.log("• Libros - recursos que se prestan")
78
- console.log("• Usuarios - quienes solicitan préstamos")
79
- console.log("• Préstamos - relación temporal entre libro y usuario")
80
- console.log("• Biblioteca - coordina todo el proceso")
81
-
82
- console.log("\n🎯 Propósito determinado:")
83
- console.log("Facilitar el acceso organizado a recursos bibliográficos")
84
-
85
- console.log("\n🔗 Relaciones ordenadas:")
86
- console.log("• Usuario solicita → Biblioteca evalúa → Préstamo se crea")
87
- console.log("• Libro cambia estado → Usuario recibe acceso → Plazo se establece")
88
- console.log("• Vencimiento llega → Usuario devuelve → Libro se libera")
89
-
90
- await this.waitForEnter("\nPresiona Enter para ver la descomposición en objetos...")
91
- }
92
-
93
- async step3_ObjectIdentification() {
94
- console.clear()
95
- console.log("Descomposición en objetos:")
96
-
97
- const bookCode = `class Book {
98
- constructor(title, author, isbn) {
99
- this.title = title
100
- this.author = author
101
- this.isbn = isbn
102
- this.isLoaned = false
103
- }
104
-
105
- isAvailable() {
106
- return !this.isLoaned
107
- }
108
-
109
- markAsLoaned() {
110
- this.isLoaned = true
111
- }
112
-
113
- markAsReturned() {
114
- this.isLoaned = false
115
- }
116
- }`
117
-
118
- this.printCodeWithColors("📄 Clase Book", bookCode)
119
-
120
- await this.waitForEnter("\nPresiona Enter para ver User...")
121
-
122
- const userCode = `class User {
123
- constructor(name, email, maxLoans = 3) {
124
- this.name = name
125
- this.email = email
126
- this.maxLoans = maxLoans
127
- this.currentLoans = []
128
- }
129
-
130
- canBorrow() {
131
- return this.currentLoans.length < this.maxLoans
132
- }
133
-
134
- addLoan(loan) {
135
- this.currentLoans.push(loan)
136
- }
137
-
138
- removeLoan(loan) {
139
- const index = this.currentLoans.indexOf(loan)
140
- if (index > -1) this.currentLoans.splice(index, 1)
141
- }
142
- }`
143
-
144
- this.printCodeWithColors("📄 Clase User", userCode)
145
-
146
- await this.waitForEnter("\nPresiona Enter para ver Loan...")
147
-
148
- const loanCode = `class Loan {
149
- constructor(user, book, durationDays = 14) {
150
- this.user = user
151
- this.book = book
152
- this.startDate = new Date()
153
- this.dueDate = new Date(Date.now() + durationDays * 24 * 60 * 60 * 1000)
154
- this.returned = false
155
- }
156
-
157
- isOverdue() {
158
- return !this.returned && new Date() > this.dueDate
159
- }
160
-
161
- calculateFine() {
162
- if (!this.isOverdue()) return 0
163
- const daysLate = Math.ceil((new Date() - this.dueDate) / (24 * 60 * 60 * 1000))
164
- return daysLate * 5 // $5 por día
165
- }
166
-
167
- returnBook() {
168
- this.returned = true
169
- this.book.markAsReturned()
170
- this.user.removeLoan(this)
171
- }
172
- }`
173
-
174
- this.printCodeWithColors("📄 Clase Loan", loanCode)
175
-
176
- await this.waitForEnter("\nPresiona Enter para ver Library...")
177
-
178
- console.log("\nclass Library {")
179
- console.log(" constructor() {")
180
- console.log(" this.books = []")
181
- console.log(" this.users = []")
182
- console.log(" this.loans = []")
183
- console.log(" }")
184
- console.log("")
185
- console.log(" lendBook(user, book) {")
186
- console.log(" if (!user.canBorrow()) return null")
187
- console.log(" if (!book.isAvailable()) return null")
188
- console.log("")
189
- console.log(" const loan = new Loan(user, book)")
190
- console.log(" book.markAsLoaned()")
191
- console.log(" user.addLoan(loan)")
192
- console.log(" this.loans.push(loan)")
193
- console.log(" return loan")
194
- console.log(" }")
195
- console.log("")
196
- console.log(" returnBook(loan) {")
197
- console.log(" loan.returnBook()")
198
- console.log(" return loan.calculateFine()")
199
- console.log(" }")
200
- console.log("")
201
- console.log(" getOverdueLoans() {")
202
- console.log(" return this.loans.filter(loan => loan.isOverdue())")
203
- console.log(" }")
204
- console.log("}")
205
-
206
- await this.waitForEnter("\nPresiona Enter para ver la interacción...")
207
-
208
- console.clear()
209
- console.log("Ejemplo de uso:")
210
- console.log("")
211
- console.log("const library = new Library()")
212
- console.log("const book = new Book('1984', 'George Orwell', '978-0451524935')")
213
- console.log("const user = new User('Ana García', 'ana@email.com')")
214
- console.log("")
215
- console.log("// Los objetos interactúan entre sí")
216
- console.log("const loan = library.lendBook(user, book)")
217
- console.log("console.log(book.isAvailable()) // false")
218
- console.log("console.log(user.canBorrow()) // true (2 préstamos disponibles)")
219
- console.log("")
220
- console.log("// Simular libro vencido")
221
- console.log("loan.dueDate = new Date(Date.now() - 24 * 60 * 60 * 1000)")
222
- console.log("console.log(loan.isOverdue()) // true")
223
- console.log("console.log(loan.calculateFine()) // 5")
224
- console.log("")
225
- console.log("// Devolver libro")
226
- console.log("const fine = library.returnBook(loan)")
227
- console.log("console.log(book.isAvailable()) // true")
228
-
229
- await this.waitForEnter("\nPresiona Enter para la conclusión...")
230
- }
231
-
232
- async conclusion() {
233
- console.clear()
234
- console.log("🎓 Conclusión: La Descomposición de Sistemas")
235
- console.log("=" .repeat(50))
236
- console.log("🎯 Hemos demostrado que:")
237
-
238
- console.log("\n1️⃣ Sistema como totalidad deductiva:")
239
- console.log(" • De 'biblioteca digital' se deduce naturalmente: libros + usuarios")
240
- console.log(" • Esta deducción revela la interacción fundamental del sistema")
241
-
242
- console.log("\n2️⃣ Sistema como conjunto con propósito:")
243
- console.log(" • Elementos identificados: Book, User, Loan, Library")
244
- console.log(" • Relaciones ordenadas: solicitud → evaluación → préstamo → devolución")
245
- console.log(" • Propósito determinado: acceso organizado a recursos")
246
-
247
- console.log("\n⚡ La parte difícil:")
248
- console.log("¿Cómo decidimos que necesitábamos exactamente estos 4 objetos?")
249
- console.log("¿Por qué no 3? ¿Por qué no 10? ¿Cuál es el criterio?")
250
-
251
- console.log("\n🔍 Criterio de descomposición:")
252
- console.log("• Book - responsabilidad de estado propio")
253
- console.log("• User - responsabilidad de sus límites")
254
- console.log("• Loan - responsabilidad de la relación temporal")
255
- console.log("• Library - responsabilidad de coordinación")
256
-
257
- console.log("\n📚 Conexión con lecciones siguientes:")
258
- console.log("• Lección 2: Los objetos interactúan a través de solicitudes")
259
- console.log("• Lección 3: Las solicitudes son la única forma de ejecutar operaciones")
260
- console.log("• Lección 4-6: Cómo definir esas interacciones correctamente")
261
-
262
- console.log("\n💭 Reflexión:")
263
- console.log("La descomposición en objetos es difícil porque requiere identificar")
264
- console.log("las responsabilidades naturales que se deducen del sistema.")
265
-
266
- await this.waitForEnter("\n✨ ¡Lección 1 completada! Presiona Enter para continuar...")
267
- }
268
-
269
- formatCode(code) {
270
- // ANSI color codes
271
- const colors = {
272
- keyword: '\x1b[35m', // magenta for keywords like class, constructor
273
- property: '\x1b[32m', // green for this.property
274
- string: '\x1b[33m', // yellow for strings
275
- comment: '\x1b[90m', // gray for comments
276
- reset: '\x1b[0m' // reset color
277
- }
278
-
279
- return code
280
- .replace(/\b(class|constructor|return|if|const|let|new)\b/g, `${colors.keyword}$1${colors.reset}`)
281
- .replace(/\bthis\./g, `${colors.property}this.${colors.reset}`)
282
- .replace(/'([^']*)'/g, `${colors.string}'$1'${colors.reset}`)
283
- .replace(/"([^"]*)"/g, `${colors.string}"$1"${colors.reset}`)
284
- .replace(/\/\/.*$/gm, `${colors.comment}$&${colors.reset}`)
285
- }
286
-
287
- printCodeWithColors(title, code) {
288
- console.log(`\n${title}`)
289
- console.log("━".repeat(50))
290
-
291
- code.split('\n').forEach(line => {
292
- const formattedLine = this.formatCode(line)
293
- console.log(formattedLine)
294
- })
295
-
296
- console.log("━".repeat(50))
297
- }
298
-
299
- async waitForEnter(message) {
300
- return new Promise((resolve) => {
301
- this.rl.question(message, () => {
302
- console.log("\n\n") // Add extra spacing after each interaction
303
- resolve()
304
- })
305
- })
306
- }
307
- }
308
-
309
- // Para usar la lección independientemente
310
- if (import.meta.url === `file://${process.argv[1]}`) {
311
- const lesson = new Lesson1SystemDecomposition()
312
- await lesson.start()
313
- }
@@ -1,309 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // LECCIÓN 2: Los objetos interactúan entre sí a través de solicitudes
4
- // Enfoque práctico: Demostrar cómo los objetos se comunican sin acceder directamente a datos internos
5
-
6
- import { createInterface } from 'readline'
7
-
8
- export class Lesson2ObjectRequests {
9
- constructor() {
10
- this.rl = createInterface({
11
- input: process.stdin,
12
- output: process.stdout
13
- })
14
- }
15
-
16
- async start() {
17
- console.log("\n💡 ¿Qué significa esto exactamente?")
18
- console.log("- Los objetos NO acceden directamente a los datos de otros objetos")
19
- console.log("- En lugar de eso, hacen SOLICITUDES específicas")
20
- console.log("- Cada solicitud tiene un propósito claro y definido")
21
-
22
- await this.waitForEnter("\nPresiona Enter para comenzar el ejercicio práctico...")
23
-
24
- await this.practicalExercise()
25
- await this.conclusion()
26
-
27
- this.rl.close()
28
- }
29
-
30
- async practicalExercise() {
31
- console.clear()
32
- console.log("🛠️ EJERCICIO PRÁCTICO: Sistema de Mensajería")
33
- console.log("=" .repeat(50))
34
- console.log("🎯 Vamos a ver cómo los objetos se solicitan información sin acceso directo")
35
- console.log("\nSistema: Chat entre usuarios")
36
- console.log("Objetos: User, Message, ChatRoom")
37
-
38
- await this.waitForEnter("\nPresiona Enter para ver el ANTI-PATRÓN...")
39
-
40
- await this.step1_ShowAntiPattern()
41
- await this.step2_ShowCorrectPattern()
42
- await this.step3_RequestTypes()
43
- await this.step4_ComplexInteraction()
44
- }
45
-
46
- async step1_ShowAntiPattern() {
47
- console.clear()
48
- console.log("❌ ANTI-PATRÓN: Acceso Directo (INCORRECTO)")
49
- console.log("=" .repeat(45))
50
- console.log("Veamos qué NO debemos hacer:")
51
-
52
- console.log("\n// ❌ MALO: Acceso directo a datos internos")
53
- console.log(`class ChatRoom {
54
- addMessage(user, text) {
55
- // ❌ Accediendo directamente a user.name
56
- if (user.name && user.name.length > 0) {
57
- // ❌ Accediendo directamente a user.isActive
58
- if (user.isActive === true) {
59
- const message = new Message(user.name, text)
60
- this.messages.push(message)
61
- }
62
- }
63
- }
64
- }`)
65
-
66
- console.log("\n🚨 Problemas del acceso directo:")
67
- console.log("• ChatRoom conoce la estructura interna de User")
68
- console.log("• Si User cambia, ChatRoom se rompe")
69
- console.log("• No hay control sobre qué se accede")
70
- console.log("• Violación de encapsulación")
71
-
72
- await this.waitForEnter("\nPresiona Enter para ver la forma CORRECTA...")
73
- }
74
-
75
- async step2_ShowCorrectPattern() {
76
- console.clear()
77
- console.log("✅ PATRÓN CORRECTO: Solicitudes (CORRECTO)")
78
- console.log("=" .repeat(45))
79
- console.log("Ahora veamos cómo debe ser:")
80
-
81
- console.log("\n// ✅ BUENO: Comunicación a través de solicitudes")
82
- console.log(`class User {
83
- constructor(name) {
84
- this.#name = name
85
- this.#isActive = true
86
- }
87
-
88
- // 🔑 SOLICITUD: getName()
89
- getName() {
90
- return this.#name
91
- }
92
-
93
- // 🔑 SOLICITUD: isCurrentlyActive()
94
- isCurrentlyActive() {
95
- return this.#isActive
96
- }
97
-
98
- // 🔑 SOLICITUD: canSendMessage()
99
- canSendMessage() {
100
- return this.#isActive && this.#name.length > 0
101
- }
102
- }`)
103
-
104
- await this.waitForEnter("\nPresiona Enter para ver cómo ChatRoom usa las solicitudes...")
105
-
106
- console.log("\n// ✅ ChatRoom usa SOLICITUDES, no acceso directo")
107
- console.log(`class ChatRoom {
108
- addMessage(user, text) {
109
- // ✅ SOLICITUD: ¿puede enviar mensajes?
110
- if (user.canSendMessage()) {
111
- // ✅ SOLICITUD: dame tu nombre
112
- const userName = user.getName()
113
- const message = new Message(userName, text)
114
- this.messages.push(message)
115
- }
116
- }
117
-
118
- getActiveUsers() {
119
- return this.users.filter(user =>
120
- // ✅ SOLICITUD: ¿estás activo?
121
- user.isCurrentlyActive()
122
- )
123
- }
124
- }`)
125
-
126
- console.log("\n🌟 Beneficios de las solicitudes:")
127
- console.log("• ChatRoom no conoce la estructura interna de User")
128
- console.log("• User controla qué información expone")
129
- console.log("• Cambios internos en User no afectan ChatRoom")
130
- console.log("• Cada solicitud tiene un propósito específico")
131
-
132
- await this.waitForEnter("\nPresiona Enter para ver tipos de solicitudes...")
133
- }
134
-
135
- async step3_RequestTypes() {
136
- console.clear()
137
- console.log("🔍 TIPOS DE SOLICITUDES")
138
- console.log("=" .repeat(30))
139
- console.log("Las solicitudes pueden ser de diferentes tipos:")
140
-
141
- console.log("\n1️⃣ SOLICITUDES DE CONSULTA (Query)")
142
- console.log(" • user.getName() → devuelve información")
143
- console.log(" • user.isCurrentlyActive() → devuelve estado")
144
- console.log(" • message.getTimestamp() → devuelve dato")
145
-
146
- console.log("\n2️⃣ SOLICITUDES DE ACCIÓN (Command)")
147
- console.log(" • user.setActive(false) → cambia estado")
148
- console.log(" • message.markAsRead() → ejecuta acción")
149
- console.log(" • chatRoom.addUser(user) → modifica colección")
150
-
151
- console.log("\n3️⃣ SOLICITUDES DE VALIDACIÓN (Validation)")
152
- console.log(" • user.canSendMessage() → verifica capacidad")
153
- console.log(" • message.isValid() → verifica integridad")
154
- console.log(" • chatRoom.hasPermission(user) → verifica acceso")
155
-
156
- await this.waitForEnter("\nPresiona Enter para ver una interacción compleja...")
157
-
158
- console.clear()
159
- console.log("💬 EJEMPLO: Enviar mensaje con validaciones")
160
- console.log("=" .repeat(45))
161
-
162
- console.log("\n// Los objetos colaboran solo a través de solicitudes")
163
- console.log(`function sendMessage(chatRoom, user, text) {
164
- // 🔍 SOLICITUD: ¿el usuario puede enviar?
165
- if (!user.canSendMessage()) {
166
- console.log("Usuario no puede enviar mensajes")
167
- return false
168
- }
169
-
170
- // 🔍 SOLICITUD: ¿el usuario tiene permisos en este chat?
171
- if (!chatRoom.hasPermission(user)) {
172
- console.log("Sin permisos en este chat")
173
- return false
174
- }
175
-
176
- // 🔍 SOLICITUD: ¿el texto es válido?
177
- const message = new Message(user.getName(), text)
178
- if (!message.isValid()) {
179
- console.log("Mensaje inválido")
180
- return false
181
- }
182
-
183
- // ⚡ SOLICITUD: agregar el mensaje
184
- chatRoom.addMessage(user, text)
185
-
186
- // 🔍 SOLICITUD: notificar a usuarios activos
187
- const activeUsers = chatRoom.getActiveUsers()
188
- activeUsers.forEach(activeUser => {
189
- // 🔍 SOLICITUD: notificar
190
- activeUser.notifyNewMessage(message)
191
- })
192
-
193
- return true
194
- }`)
195
-
196
- console.log("\n🎯 Observa: En ningún momento accedemos directamente a")
197
- console.log(" user.#name, user.#isActive, chatRoom.#messages, etc.")
198
- console.log(" Todo pasa por SOLICITUDES específicas.")
199
-
200
- await this.waitForEnter("\nPresiona Enter para la demostración final...")
201
- }
202
-
203
- async step4_ComplexInteraction() {
204
- console.clear()
205
- console.log("🎭 DEMOSTRACIÓN: Interacción Completa")
206
- console.log("=" .repeat(40))
207
- console.log("Veamos todos los objetos interactuando:")
208
-
209
- console.log("\n// Crear objetos")
210
- console.log("const chatRoom = new ChatRoom('Desarrollo')")
211
- console.log("const ana = new User('Ana')")
212
- console.log("const carlos = new User('Carlos')")
213
- console.log("")
214
- console.log("// Agregar usuarios al chat")
215
- console.log("chatRoom.addUser(ana) // SOLICITUD")
216
- console.log("chatRoom.addUser(carlos) // SOLICITUD")
217
- console.log("")
218
- console.log("// Ana envía mensaje")
219
- console.log("sendMessage(chatRoom, ana, 'Hola a todos!')")
220
- console.log("")
221
- console.log("// Secuencia de SOLICITUDES que se ejecutan:")
222
- console.log("// 1. ana.canSendMessage() → true")
223
- console.log("// 2. chatRoom.hasPermission(ana) → true")
224
- console.log("// 3. ana.getName() → 'Ana'")
225
- console.log("// 4. message.isValid() → true")
226
- console.log("// 5. chatRoom.addMessage(ana, text)")
227
- console.log("// 6. chatRoom.getActiveUsers() → [ana, carlos]")
228
- console.log("// 7. carlos.notifyNewMessage(message)")
229
-
230
- console.log("\n💡 Resultado:")
231
- console.log("✅ Ana: Mensaje enviado")
232
- console.log("📬 Carlos: Notificación recibida")
233
-
234
- await this.waitForEnter("\nPresiona Enter para ver qué pasa si Carlos se desconecta...")
235
-
236
- console.log("\n// Carlos se desconecta")
237
- console.log("carlos.setActive(false) // SOLICITUD")
238
- console.log("")
239
- console.log("// Ana envía otro mensaje")
240
- console.log("sendMessage(chatRoom, ana, 'Carlos, ¿estás ahí?')")
241
- console.log("")
242
- console.log("// Secuencia de SOLICITUDES:")
243
- console.log("// 1-5. Igual que antes...")
244
- console.log("// 6. chatRoom.getActiveUsers() → [ana] // ¡Carlos ya no aparece!")
245
- console.log("// 7. Solo ana.notifyNewMessage() se ejecuta")
246
-
247
- console.log("\n💡 Resultado:")
248
- console.log("✅ Ana: Mensaje enviado")
249
- console.log("😴 Carlos: No recibe notificación (está inactivo)")
250
-
251
- console.log("\n🎯 Observación clave:")
252
- console.log("Los objetos cambian su comportamiento interno, pero las")
253
- console.log("SOLICITUDES siguen siendo las mismas. La interacción es estable.")
254
-
255
- await this.waitForEnter("\nPresiona Enter para la conclusión...")
256
- }
257
-
258
- async conclusion() {
259
- console.clear()
260
- console.log("🎓 CONCLUSIÓN: Interacción a través de Solicitudes")
261
- console.log("=" .repeat(50))
262
- console.log("🎯 Hemos demostrado que:")
263
-
264
- console.log("\n1️⃣ Los objetos NUNCA acceden directamente a datos internos")
265
- console.log("2️⃣ Toda comunicación ocurre a través de SOLICITUDES específicas")
266
- console.log("3️⃣ Cada solicitud tiene un propósito claro y definido")
267
- console.log("4️⃣ Los objetos controlan qué información exponen")
268
-
269
- console.log("\n🔑 Tipos de solicitudes vistas:")
270
- console.log("• CONSULTA: getName(), isCurrentlyActive()")
271
- console.log("• ACCIÓN: setActive(), addMessage()")
272
- console.log("• VALIDACIÓN: canSendMessage(), hasPermission()")
273
-
274
- console.log("\n🌟 Beneficios fundamentales:")
275
- console.log("• Encapsulación preservada")
276
- console.log("• Flexibilidad para cambios internos")
277
- console.log("• Interacciones estables y predecibles")
278
- console.log("• Control total sobre el acceso a datos")
279
-
280
- console.log("\n📚 Conexión con otras lecciones:")
281
- console.log("• Lección 1: Los objetos que identificamos ahora interactúan")
282
- console.log("• Lección 3: Las solicitudes son la ÚNICA forma de ejecutar operaciones")
283
- console.log("• Lecciones 4-6: Cómo definir formalmente estas solicitudes")
284
-
285
- console.log("\n💭 Reflexión:")
286
- console.log("¿Te imaginas un mundo donde pudieras acceder directamente")
287
- console.log("a la cuenta bancaria de cualquier persona? ¡Sería un caos!")
288
- console.log("Los objetos funcionan igual: solicitudes controladas, acceso seguro.")
289
-
290
- console.log("\n🏆 Ahora entiendes por qué los objetos interactúan a través")
291
- console.log("de solicitudes: es la base de la comunicación segura y ordenada.")
292
-
293
- await this.waitForEnter("\n✨ ¡Lección 2 completada! Presiona Enter para salir...")
294
- }
295
-
296
- async waitForEnter(message) {
297
- return new Promise((resolve) => {
298
- this.rl.question(message, () => {
299
- resolve()
300
- })
301
- })
302
- }
303
- }
304
-
305
- // Para usar la lección independientemente
306
- if (import.meta.url === `file://${process.argv[1]}`) {
307
- const lesson = new Lesson2ObjectRequests()
308
- await lesson.start()
309
- }