17 Mar 2010 - 14:11 (http://www.jsmanrique.es/2010/03/17/nokia-n900-vs-googlehtc-nexus-one-la-importancia-del-diseno-industrial/#comments comentario/s)
Ya hay varias revisiones y comparativas del Nokia N900 frente al Nexus One (sólo hay que buscar en Google), pero yo voy a destacar algo que los diferencia y que ha cobrado especial importancia por experiencia personal.
Los Nokia siempre han sido teléfonos con tradición de ser duros y resistentes, y ya me ha caído alguna vez el N900 al suelo. El otro día cayó boca abajo y deslizó sobre un suelo rugoso de gres y claro, piensas: Adiós pantalla. Y, ¡oh, sorpresa!, la pantalla estaba intacta. ¿Cómo?¿Por qué?
Muy sencillo, el marco que tiene la pantalla del N900 la cubre por los bordes, con lo cual, si colocas el teléfono boca abajo, apoya sobre dicho marco, y si lo deslizas, lo mismo. En definitiva, el marco se ha rayado ligeramente, pero la pantalla sigue intacta.
¿Qué hubiera pasado con el Nexus One, u otros teléfonos donde la pantalla está al ras con el marco lateral? Pues probablemente o se raya o lo que puede ser peor, que debido a que parte del golpe lo absorbe la pantalla, que esta se rompa.. y todos sabemos, que siempre dicen eso de que «la pantalla es lo único que no cubre la garantía».
Así que visto lo visto, un 10 a Nokia en diseño industrial.
17 Mar 2010 - 02:48 (http://www.carballude.es/Blog/?p=510#comments comentario/s)
Seguramente todos sabéis lo que es el patrón Singleton, pero por si alguien faltó a clase ese día, es un método de asegurarse de que una clase es instanciada una única vez independientemente del número de veces que se la llame.
El sistema de lograrlo es sencillo:
Se crea una variable estática del mismo tipo que la clase en la que se guardará una referencia a si misma (hasta la primera instancia valdrá null)
- Se crea un método estático público que creará una instancia y asignará su valor a la variable estática.
- Se hará privado el constructor, con lo que la única clase capaz de llamarlo (y por tanto crear el objeto) será ella misma.
-
Esto hace que nadie pueda usar new Clase(); sino que debe accederse llamando al método estático (típicamente llamado Clase.GetInstance();)
Bueno, supongamos que tenemos la siguiente implementación:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| using System;
using System.Collections.Generic;
using System.Text;
namespace ReflectionTest
{
public class Singleton
{
private static Singleton INSTANCE = null;
private static int ID = 0;
private int _instanceId;
private Singleton()
{
_instanceId = ++ID;
Console.WriteLine("Singleton created with ID={0}", Singleton.ID);
}
public static Singleton GetInstance()
{
if (INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
public void WhoAmI()
{
Console.WriteLine("I am instance number: {0}", _instanceId);
}
}
} |
Si intentamos hacer un new Singleton() el compilador nos dirá que nanai, que el constructor es privado y no podemos. Nada nos impide hacer dos llamadas al método GetInstance(), pero se comportará devolviéndonos siempre la primera instancia:
1
2
3
4
| Singleton singleton = Singleton.GetInstance();
Singleton singleton1 = Singleton.GetInstance();
singleton.WhoAmI();
singleton1.WhoAmI(); |
El resultado sería:
Singleton created with ID=1
I am instance number: 1
I am instance number: 1
Es decir, aunque hacemos dos llamadas sólo se crea un objeto (vamos, que el Singleton funciona) y efectivamente la variable de control que he introducido para hacer las cosas más claras nos indica que ambas llamadas retornan la instancia número uno.
Vale, hasta aquí todo correcto. El problema viene cuando se juega con reflectividad. En algunos casos la gente carga las clases haciendo uso de esta técnica… pero no se da cuenta de los posibles efectos laterales que puede tener. ¿Qué pasaría si intentáramos cargar la clase Singleton haciendo uso de reflectividad? Vamos a probarlo con el siguiente código, que llamará una vez a la clase Singleton, luego la cargará por reflectividad y veremos a ver si se rompe alguna tripa:
1
2
3
4
5
6
7
8
9
10
| //Llamamos a GetInstance de forma "normal"
Singleton singleton = Singleton.GetInstance();
//Por reflectividad obtenemos el constructor de la clase Singleton
ConstructorInfo constructor = typeof(Singleton).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, System.Type.EmptyTypes, null);
//Usando la información obtenida por reflectividad, invocamos al constructor
object compiled = constructor.Invoke(null);
//Como sabemos que es una clase Singleton le hacemos un ahormado para facilitarnos las cosas
Singleton reflected = (Singleton)compiled;
singleton.WhoAmI();
reflected.WhoAmI(); |
¿Qué salida esperaríais obtener? Siguiendo la teoría Singleton, esto debería ser exactamente igual que lo anterior, sin embargo la salida nos descoloca un poco:
Singleton created with ID=1
Singleton created with ID=2
I am instance number: 1
I am instance number: 2
¡Meeeeeec! Tripa rota. ¿Por qué ocurre esto? Bueno, la implementación que he usado del patrón de diseño Singleton se basa en la creencia (fundada) de que las variables estáticas de una clase sólo pueden tener un valor que será compartido por todas las instancias de la clase y que un método privado no puede ser accesible desde otras clases. Ambas cosas son correctas… casi siempre. La excepción está en la reflectividad.
A día de hoy no conozco ninguna implementación del Singleton que permita evitar este comportamiento. Claro que hasta hace 30 minutos que me dio por pensar esto no sabía que el Singleton podía ser burlado mediante reflectividad, así que a saber…