2010-09-16 22 views
5

Soy un nuevo programador, así que disculpe cualquier tontería de esta pregunta, ¿cómo el siguiente código está encapsulando datos privados? -¿Dónde está la encapsulación?

public class SomeClass 
{ 
    private int age; 

    public int Age 
    { 
     get { return age; } 
     set { age = value; } 
    } 

    public SomeClass(int age) 
    { 
     this.age = age; 
    } 
} 

quiero decir, sin ninguna lógica restricción o lógica de filtrado en las propiedades, cómo es el código de seguridad diferente del folowing uno -

public class SomeClass 
{ 
    public int age; 

    public SomeClass(int age) 
    { 
     this.age = age; 
    } 
} 

es el primer código que ofrezca cualquier encapsulación en absoluto?

Respuesta

8

Se proporciona una pieza de encapsulación: es decir, "hay una propiedad Age se puede obtener y definir, pero no voy a decir cómo estoy poniendo en práctica la misma."

No es una encapsulación muy fuerte, pero hace mantiene los detalles de implementación separados de la API pública. Sin cambiar la API pública en absoluto, podría comenzar a almacenar la edad en otro lugar: en dos campos short, en un servicio en alguna parte, como parte de un campo long o lo que sea. Podría poner el registro en la propiedad para ver con qué frecuencia se usa. Podría agregar un evento que se active cuando cambie la edad (eso es un cambio de API, pero no afectará a las personas que llaman).

EDIT: Una cosa a tener en cuenta: a pesar de que esto no hace nada ahora, el cambio a hacer que haga algo más tarde es a la vez fuente y compatible binario. El cambio de un campo para convertirse en una propiedad es no compatible con versiones anteriores, ya sea en formato fuente o binario. En la mayoría de los casos de serán compatibles con la fuente, pero no serán compatibles con binarios. En algunos casos, la fuente ya no se compilará. En más malvado (y artificial, ciertamente) ambas versiones se construirán, pero con diferentes efectos.

También tenga en cuenta que a partir de C# 3, se puede declarar una propiedad trivial tan fácilmente como un campo:

public int Age { get; set; } 

Tengo una article about all of this que proporciona más detalles.

+0

... pero es él por cualquier medio "proteger" mis datos privados? pensé que la protección de datos privados era un propósito importante que la encapsulación sirve :( – atiyar

+1

encapsulación le da la capacidad de proteger sus datos privados. Es como decir "¿Cómo es que no pasa nada cuando pulso estas rocas con este martillo? pensé martillos eran para la construcción .. cosas" es simplemente una herramienta que no va a obligar a usarlo con sensatez – recursive

+1

@Nero:.. puede ser sobre los datos ... puede ser sobre detalles de implementación Ambos son parte de encapsulación –

0

En su primer ejemplo, SomeClass.Age es una propiedad. El campo "respaldo" de la propiedad es privado. En su segundo ejemplo, SomeClass.age es un campo público. Si bien en muchos casos puede no haber diferencia, elegir una propiedad sobre un campo le da la capacidad de cambiar la implementación sin cambiar la API, o "forma" de la clase. Tal vez quiera hacer algo (persistir o notificar) cada vez que cambie la propiedad; eso sería imposible de hacer con un campo.

+0

Se podría convertir el campo en una propiedad muy fácilmente ;-) –

+1

hay diferencias. Las propiedades no se pueden pasar como 'ref'. Los campos no pueden estar enlazados a datos. – recursive

2

Este es un ejemplo poco claro. Como ha señalado correctamente, la propiedad no parece hacer nada.

Pero podría. Por ejemplo, SomeClass podría poner restricciones sobre cómo se modifica la propiedad Age (por ejemplo, no cambiar la edad a un valor incorrecto como -2 u 823). Además, SomeClass no necesita representar la edad como un int internamente. La edad podría ser el resultado de un cálculo (por ejemplo restando la fecha de hoy de la fecha de nacimiento de una persona) o podría almacenarse dentro de SomeClass como otro tipo de datos (por ejemplo, un byte, largo o doble).

+0

eso es MUCHO "podría ser", hombre. Estoy preguntando sobre el código, ya que actualmente "ES". porque he visto muchos códigos (por supuesto, no es el de un experto) como este, campo privado y propiedad pública sin lógica de restricción. ¿No se supone que las propiedades proporcionan algún tipo de encapsulación para proteger mis datos privados? y si NO lo están haciendo, ¿hay alguna diferencia entre las dos muestras de código presened?eso es todo lo que estoy preguntando porque no tengo idea. – atiyar

+0

@Nero: No sé por qué dices "no experto": en algunos casos, una propiedad publicable y trivial pública es exactamente lo que debes tener. Aún es mejor que un campo público. –

+0

@Nero: Sí, la diferencia semántica entre una propiedad y un campo público es mínima, pero eso no es lo importante. El objetivo de una buena ingeniería de software no es solo escribir código que funcione; es escribir código que sea comprensible y extensible. Por lo tanto, lo que "podría ser" importa tanto como lo que "es". – joshdick

2

quiero decir, sin ninguna lógica restricción o lógica de filtrado en las propiedades, cómo es el anterior una diferente de las folowing uno

No es el hecho de que haya o no haya aplicado la lógica de validación en la propiedad, la encapsulación aquí significa que nadie puede acceder/modificar directamente sus datos privados. El único acceso disponible es pasar por la propiedad.

Utilizando el código de fondo, cualquiera puede genereate excepciones y causar todo tipo de estragos, ya que pueden hacer lo que quieran a sus datos.

Usar el código superior como está escrito permite este mismo estrago, pero en cualquier momento en el futuro puede implementar una lógica de restricción en la propiedad y no tener que modificar una API para los usuarios de esta clase.

1

Está encapsulado, o envoltura, los cambios en la variable privada age. La variable privada Age no puede ser modificada directamente por los llamantes externos, solo a través de los métodos public dados. Está configurando una interfaz para que los cambios futuros en age no rompan las llamadas. El beneficio es para los llamantes externos en el futuro, por lo que es difícil de ver ahora.

0

es el primer código que ofrezca cualquier encapsulación en absoluto?

NO (al menos el código en particular que usted escribió).

Las 2 piezas de código son casi los mismos. El primero no proporciona ninguna diferencia útil en comparación con el segundo (como se escribe el código).

Al utilizar getters y setters, puede restringir el acceso a las variables privadas. Esto podría ser una forma de encapsulación.

decir

private int x 

public int getInt(String password){ 
if(password == 'RealPassword'){ 
    return x 
    } 
}