Lección 68 de 170

Scope no es ownership

Curso de desarrollo de videojuegos con IA

Distingue el límite de acceso real de un estado de los sistemas que legítimamente necesitan leerlo y clasifica su autoridad, lifetime y persistencia.

990. Identidad de la lección

Módulo
3.2 — Estado global y local
Lección
1 — Scope no es ownership
Tipo académico
Concepto
Tipo de esquema
texto
Orden
1 dentro del módulo
Tiempo estimado
30–45 minutos, incluida la práctica

991. Objetivo de aprendizaje

Después de esta lección, podrás identificar el límite de acceso actual de un estado, compararlo con los sistemas que legítimamente necesitan acceder a él y clasificar por separado su writer autorizado, lifetime y persistencia.

992. Por qué importa

Un valor puede ser accesible desde toda la aplicación aunque solo dos sistemas necesiten leerlo. Es fácil pasar por alto ese desajuste cuando el scope se describe únicamente como una lista de readers previstos.

Un acceso amplio puede ser cómodo, pero la comodidad no demuestra que el estado deba ocupar un límite global. Tampoco concede permiso de escritura a todos los sistemas. Cuando se mezclan estas decisiones, el código puede acumular writers que compiten, dependencias ocultas, copias desactualizadas y estados que duran más que el objeto al que describen.

El objetivo no es volver privado cada valor. El objetivo es explicitar cuatro decisiones: quién puede acceder al estado ahora, quién debería necesitar acceso, quién puede modificarlo y cuánto tiempo debe existir o conservarse.

993. Conocimientos previos

Debes poder rastrear una acción a través de su creación, actualización, comunicación y teardown, como se practicó en 3.1 L2 — Trace one action through the architecture. También debes reconocer componentes, servicios, eventos y owners de runtime.

994. Concepto central

El scope es el límite de acceso real del estado. El ownership es la autoridad para validar y confirmar cambios. Los readers necesarios son un requisito de diseño que permite evaluar si el scope actual es adecuado.

Formula dos preguntas de acceso diferentes:

  1. Acceso actual: ¿Qué sistemas pueden acceder al estado con el diseño actual?
  2. Necesidad legítima: ¿Qué sistemas realmente necesitan leerlo o solicitar cambios?

Si las respuestas no coinciden, conviene revisar el diseño. Por ejemplo, una moneda accesible globalmente puede ser necesaria solo para la funcionalidad de economía y su UI. Su scope actual es de aplicación/global aunque el conjunto de readers legítimos sea pequeño.

Usa etiquetas de scope coherentes:

  • Componente/objeto: solo se puede acceder desde un objeto o uno de sus componentes.
  • Funcionalidad: se puede acceder dentro de una funcionalidad delimitada, como inventario o combate.
  • Escena o partida: se puede acceder desde los sistemas que participan en la escena o partida actual.
  • Sesión: se puede acceder entre escenas durante la sesión de juego actual.
  • Aplicación/global: el acceso está disponible de forma amplia en toda la aplicación.

Estas etiquetas describen límites de acceso. No indican la importancia del valor ni quién es su owner.

Clasifica las demás dimensiones por separado:

  • Autoridad: ¿Qué sistema valida y confirma un cambio?
  • Lifetime: ¿Cuándo se crea el valor y cuándo se descarta?
  • Persistencia: ¿Sobrevive a un límite definido, como un cambio de escena, el final de una partida o el reinicio de la aplicación?

Por tanto, un valor puede tener acceso de aplicación/global, solo dos readers legítimos, un writer autorizado, lifetime de sesión y ninguna persistencia. Esa combinación puede revelar un scope innecesariamente amplio sin modificar la decisión de autoridad.

995. Modelo de decisión

Registra seis respuestas para cada valor de estado:

Pregunta Decisión
¿Qué sistemas pueden acceder a él ahora? Scope actual
¿Qué sistemas necesitan leerlo legítimamente? Readers necesarios
¿Cuál es el límite más estrecho que permite ese acceso? Scope deseado
¿Qué sistema valida y confirma los cambios? Autoridad
¿Cuándo se crea y se descarta? Lifetime
¿Qué límites definidos debe atravesar? Persistencia

Un patrón de comunicación útil es:

El reader observa → el requester solicita → el writer autorizado valida y confirma → los readers reciben el resultado.

Un requester no se convierte en owner por haber iniciado la acción. Del mismo modo, disponer de una referencia global no convierte automáticamente a un sistema en reader legítimo.

996. Ejemplo concreto: stamina del jugador

Supón que la stamina está almacenada en un servicio de aplicación al que puede acceder cualquier sistema.

  • Scope actual: Aplicación/global, porque cualquier sistema que obtenga la referencia del servicio puede acceder al valor.
  • Readers legítimos: El controlador de sprint y el HUD necesitan leer la stamina. Una interacción de descanso puede necesitar solicitar su recuperación.
  • Scope deseado: Funcionalidad del jugador u objeto jugador, siempre que los readers necesarios puedan observar el valor o solicitar cambios a través de ese límite.
  • Autoridad: El sistema de stamina valida el máximo, el consumo y la recuperación, y después confirma los cambios.
  • Lifetime: La instancia actual del jugador o la partida actual, según el diseño.
  • Persistencia: Ninguna si la stamina se reinicia al comenzar otra partida. Solo es persistente si el diseño exige restaurarla al cargar una partida guardada.

El servicio global no demuestra que la stamina necesite scope global. Que el HUD tenga que mostrarla no convierte al HUD en writer autorizado. Que el controlador de sprint solicite consumirla tampoco le permite saltarse las reglas de stamina.

Este ejemplo separa tres hechos que suelen confundirse:

  1. Qué puede acceder al valor en este momento.
  2. Qué necesita acceso de forma legítima.
  3. Qué sistema puede validar y confirmar un cambio.

997. Errores comunes

Error 1: Definir scope como la lista de readers previstos

Decir “el HUD y el sistema de combate leen la vida” identifica readers, pero no identifica el scope. Si la vida está en un registro global, su scope actual es de aplicación/global aunque solo esos dos sistemas deban leerla.

Error 2: Tratar el acceso global como ownership global

Un manager compartido puede permitir que la UI, el input y el código de gameplay asignen directamente el mismo valor. Esa accesibilidad no autoriza las escrituras. Nombra un sistema que posea la regla de validez y exige que los demás sistemas se limiten a leer o solicitar cambios.

Error 3: Confundir persistencia con ownership

Guardar un valor no convierte al sistema de guardado en owner de su significado de gameplay. El owner de gameplay define el estado válido. La capa de persistencia lo registra y lo restaura en un límite acordado.

Error 4: Elegir un scope amplio solo por comodidad

Una referencia global puede reducir conexiones a corto plazo, pero eso no demuestra que sistemas no relacionados deban obtener acceso. Compara el límite actual con los readers legítimos y elige el límite más estrecho que permita la colaboración necesaria.

998. Práctica guiada

Clasifica cada valor de estado. No deduzcas el scope actual a partir de los readers indicados: usa primero el mecanismo de almacenamiento o acceso para determinar quién puede acceder realmente.

  1. El estado abierto o cerrado de una puerta se almacena en el componente de la puerta. Su animación y el prompt de interacción lo leen.
  2. La moneda del jugador se almacena en un registro accesible desde toda la aplicación. El servicio de economía y la UI de la tienda necesitan leerla; el servicio de economía debe validar las compras.
  3. Una configuración gráfica está disponible mediante la funcionalidad de ajustes entre distintas escenas y debe conservarse tras reiniciar la aplicación.
  4. El flag “ya reaccionó a este trigger” de un enemigo se almacena en esa instancia y solo lo lee su componente de comportamiento.

Usa esta tabla:

Estado Límite de acceso actual Readers/requesters legítimos Límite de acceso deseado Writer autorizado Lifetime Persistencia
Estado de la puerta
Moneda
Configuración gráfica
Flag del enemigo

Usa una de estas etiquetas para los límites actuales y deseados: componente/objeto, funcionalidad, escena/partida, sesión, aplicación/global.

Después, revisa la fila de la moneda:

  • Identifica el desajuste entre el acceso actual y la necesidad legítima.
  • Decide si el límite deseado debe seguir siendo de aplicación/global o volverse más estrecho.
  • Nombra el writer autorizado sin confundirlo con el límite de acceso.
  • Explica qué suposición insegura podría permitir que la UI de la tienda u otro caller conveniente escribiera la moneda directamente.

999. Validación y evidencia

La clasificación está completa cuando cada fila incluye:

  • Un scope actual basado en quién puede acceder realmente al estado con el diseño descrito.
  • Una lista separada de readers y requesters legítimos.
  • Un scope deseado expresado con una etiqueta de límite coherente.
  • Una razón para mantener o estrechar el límite actual.
  • Un writer autorizado que posea la regla de validez.
  • Un lifetime ligado a un objeto, una funcionalidad, una partida, una sesión o la aplicación.
  • Una decisión de persistencia que indique qué límite se cruza o no se cruza.

Comprueba el trabajo con estas preguntas:

  • Si un valor es accesible globalmente pero solo dos sistemas lo necesitan, ¿anotaste aplicación/global como scope actual en lugar de usar los nombres de esos dos readers?
  • Si una UI lee un valor, ¿evitaste concederle autoridad de escritura si no posee una regla de validez?
  • Si un valor se guarda, ¿mantuviste separadas la autoridad de gameplay y las tareas de almacenamiento y restauración?

Defiende cada writer con esta frase: “Este sistema tiene la autoridad porque posee la regla que determina si el cambio es válido”.

1000. Ideas clave

  • El scope describe el límite de acceso real.
  • Los readers necesarios indican qué sistemas necesitan acceso de forma legítima.
  • Un acceso amplio frente a una necesidad estrecha puede revelar un uso global inseguro por comodidad.
  • El ownership identifica el sistema autorizado para validar y confirmar cambios.
  • Los readers y requesters no obtienen autoridad de escritura solo por tener acceso.
  • Lifetime y persistencia siguen siendo decisiones separadas del scope y la autoridad.

1001. Siguiente lección

Continúa con 3.2 L2 — Crear una hoja de ownership de estado.

1002. Comprobación

Responde estas preguntas por tu cuenta antes de leer las respuestas.

La moneda del jugador está en un registro accesible desde toda la aplicación. Solo el servicio de economía y la UI de la tienda necesitan leerla, y el servicio de economía valida las compras. ¿Qué análisis es correcto?

  • A. Scope actual: funcionalidad; scope deseado: global; writer: UI de la tienda; suposición insegura: los readers no deberían observar el estado.
  • B. Scope actual: aplicación/global; scope deseado: una funcionalidad de economía más estrecha si permite el acceso necesario; writer: servicio de economía; suposición insegura: el acceso global autoriza a cualquier caller a escribir.
  • C. Scope actual: el servicio de economía y la UI de la tienda; scope deseado: sin cambios; writers: ambos readers; suposición insegura: la persistencia es obligatoria.
  • D. Scope actual: sesión; scope deseado: objeto; writer: registro; suposición insegura: la moneda tiene lifetime.
Mostrar respuesta y explicación

Respuesta: Scope actual: aplicación/global; scope deseado: una funcionalidad de economía más estrecha si permite el acceso necesario; writer: servicio de economía; suposición insegura: el acceso global autoriza a cualquier caller a escribir.

Por qué: El registro hace que el límite actual sea de aplicación/global aunque solo dos sistemas necesiten acceso. Puede convenir un límite más estrecho dentro de economía, mientras el servicio de economía conserva la autoridad porque posee la validación de compras. El acceso global por sí solo nunca autoriza a todos los callers a escribir.

Un valor de vida es accesible globalmente, pero solo combate y el HUD necesitan leerlo. ¿Qué conclusiones están justificadas?

  • A. Su scope actual es de aplicación/global.
  • B. El conjunto de readers legítimos es menor que el límite de acceso actual.
  • C. El HUD debería convertirse en writer autorizado porque puede acceder al valor.
  • D. El desajuste indica que conviene considerar un scope deseado más estrecho.
Mostrar respuesta y explicación

Respuesta: Su scope actual es de aplicación/global.; El conjunto de readers legítimos es menor que el límite de acceso actual.; El desajuste indica que conviene considerar un scope deseado más estrecho.

Por qué: La accesibilidad real determina el scope actual. El conjunto más pequeño de readers legítimos revela un desajuste que conviene revisar, pero el acceso no concede al HUD autoridad para escribir.

Una configuración gráfica se lee entre escenas y se restaura después de reiniciar la aplicación. ¿Qué afirmación separa correctamente scope, lifetime, persistencia y autoridad?

  • A. El acceso entre escenas informa el scope, el periodo de existencia informa el lifetime, la restauración tras reiniciar es persistencia y el sistema de ajustes puede seguir siendo el writer autorizado.
  • B. Como es persistente, la capa de almacenamiento debe poseer todas las reglas de ajustes.
  • C. Su persistencia demuestra que todos los sistemas necesitan acceso global de escritura.
  • D. Scope y persistencia son idénticos porque ambos pueden cruzar límites de escena.
Mostrar respuesta y explicación

Respuesta: El acceso entre escenas informa el scope, el periodo de existencia informa el lifetime, la restauración tras reiniciar es persistencia y el sistema de ajustes puede seguir siendo el writer autorizado.

Por qué: Scope, lifetime, persistencia y autoridad responden preguntas diferentes. Restaurar un valor no transfiere las reglas de ajustes a la capa de almacenamiento.

Apoyar