Bienvenidos sean a este post, hoy hablaremos sobre algo que la mayoria considera ser una parte integral de un lenguaje orientado a objetos como es la privacidad porque el estado de cada objeto deberia ser su propio asunto interno.

Anuncios

En algunos lenguajes orientados a objetos tales como C++ o Java pueden controlar si un campo del objeto (tambien llamado variable instanciada) o un metodo es visible por fuera del objeto, en cambio otros lenguajes como SmallTalk hacen a todas las variables privadas y a todos los metodos publicos, el primer lenguaje orientado a objetos, Simula, no ofrecia ningun tipo de proteccion.

Anuncios

El principal diseño para los objetos en Lua, el cual hemos visto anteriormente, no ofrece mecanismos de privacidad, esto es en parte por consecuencia del uso de una estructura general (tablas) para representar objetos pero esto tambien refleja algunas decisiones de diseño basico detras de Lua, Lua no esta pensado para construir programas grandes donde muchos programadores estan envueltos por largos periodos, por lo contrario Lua apunta a pequeños y medianos programas como parte de un sistema mas grande, tipicamente desarrollado por uno o pocos programadores o incluso por ningun programador, por lo tanto Lua trata de evitar mucha redundancia y restricciones artificiales, si no quieres acceder a algo dentro de un objeto simplemente no lo hagas o(一︿一+)o

Anuncios

Sin embargo otro objetivo de Lua es ser flexible, ofreciendo al programador metamecanismos que la habilitan para emular muchos mecanismos diferentes, aunque el diseño basico para Lua no ofrece mecanismos de privacidad podemos implementar objeto de una manera diferente para tener control de acceso, si bien esta implementacion no es usada habitualmente nunca esta de mas conocerla, tanto porque explora algunos rincones interesantes de Lua y porque puede ser una buena solucion para otros problemas.

Anuncios

La idea basica de este diseño alternativo es representar cada objeto a traves de dos tablas, una para su estado y otra para sus operaciones, o su interfaz, el objeto en si es accedido a traves de la segunda tabla, que en realidad es atraves de las operaciones que componen la interfaz, para evitar accesos no autorizados la tabla que representa el estado de un objeto no es mantenida en el campo de otra tabla en su lugar es mantenido en el cierre de los metodos, tomemos el ejemplo de la cuenta bancaria:

Anuncios

Para representar una cuenta con este diseño se podria crear nuevos objetos ejecutando la siguiente funcion de fabrica:

function cuentaNueva(balanceInicial)
	local mismo = { balance = balanceInicial }
	
	local retirar = function(v)
			mismo.balance = mismo.balance - v
		end

	local depositar = function(v)
			mismo.balance = mismo.balance + v
		end

	local getBalance = function() return mismo.balance end

	return {
		retirar = retirar,
		depositar = depositar,
		geetBalance = getBalance
	}
end
Anuncios

Lo primero que hace es crear una tabla para mantener el estado del objeto interno y la almacena en la variable local, mismo, luego procede a crear los metodos del objeto para finalmente crear y devolver el objeto externo la cual mapea los nombres de los metodos a las implementaciones de los metodos actuales, el punto clave aqui es que estos metodos no obtienen a mismo como un parametro extra sino en su lugar acceden a mismo directamente, debido a que no hay argumentos extras no usamos la sintaxis del separador (:) para manipular tales objetos, dichos metodos son llamados como funciones comunes:

acc1 = cuentaNueva(100.00)
acc1.retirar(40.00)
print(acc1.getBalance())

Si lo ejecutamos obtendremos la siguiente salida:

> acc1 = nuevaCuenta(100.00)
> acc1.retirar(40.00)
> print(acc1.getBalance())
60.0
>
Anuncios

Este diseño da una privacidad completa a cualquier cosa almacenada en la tabla mismo, despues nuevaCuenta lo devuelve no hay forma de ganar acceso directo a esta tabla ya que podemos acceder solamente a traves de las funciones creadas dentro de nuevaCuenta, aunque nuestro ejemplo pone solo una variable de instancia dentro de la tabla privada tambien podemos almacenar todas las partes privadas de un objeto en esta tabla, ademas podemos definir metodos privados y estos seran iguales que los metodos publicos pero no los agregamos en la interfaz, por ejemplo nuestras cuentas pueden dar un credito extra del 10% para usuarios con un balance por arriba de cierto limite pero no queremos que los usuarios tengan accesos a los detalles de esa computacion, para implementar esta funcionalidad veamos el siguiente codigo:

function nuevaCuenta(balanceInicial)
	local mismo = { 
		balance = balanceInicial,
		limite = 10000.00,
	}
	
	local extra = function()
		if mismo.balance > mismo.limite then
			return mismo.balance * 0.10
		else
			return 0
		end
	end
	
	local getBalance = function() 
		return mismo.balance + extra
	end

	return {
		retirar = retirar,
		depositar = depositar,
		getBalance = getBalance
	}
end

En este caso modificamos a mismo para que tenga a balance y a limite, el primero se inicia con el valor recibido, en cambio el segundo tiene un valor fijo, la nueva funcion extra verifica si balance de la tabla mismo es mayor a limite, en caso de ser cierto devuelve el valor del balance multiplicado por 0.10 de lo contrario devuelve 0, nuestra siguiente modificacion es en getBalance donde devolvera el valor de balance mas el valor de extra, si no se cumplio la condicion anterior no se modifica el balance, y nuevamente ningun usuario podra acceder directamente a la funcion extra.

Anuncios

En resumen, hoy hemos visto la privacidad, como se usa en otros lenguajes, porque Lua no tiene un metodo directo como en otros lenguajes, como se puede emular, como se puede aplicar y como aplicarlo correctamente en Lua, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00