Pregunta

¿Es normal modificar los argumentos del setter? Imaginemos que tenemos el método setString. Y realmente queremos mantener una forma recortada de la cadena. Por lo tanto, una cadena con espacios finales no es válida, pero no queremos lanzar una excepción.

¿Cuál es la mejor solución? Para recortar el valor en el setter, por ejemplo,

public void setString(String string) {
    this.string = string.trim();
}

O recórtelo en la persona que llama (más de una vez), por ejemplo,

object.setString(string.trim());

¿O tal vez algo más?

¿Fue útil?

Solución

Sí Después de todo, ¡los setters están diseñados para este tipo de cosas! Para controlar y desinfectar los valores escritos en los campos;)

Otros consejos

Totalmente. Aquí hay un ejemplo: suponga que tiene un programa de ingeniería con diferentes tipos de unidades de medida. Mantiene los valores internos en un sistema de medición, pero convierte de todos los demás en el setter y vuelve a convertir en el getter, por ejemplo:

public double UserTemperature
{
  get
  {
    return Units.Instance.ConvertFromSystem(UnitType.Temperature, temperature);
  }
  set  
  {
    double v = Units.Instance.ConvertToSystem(UnitType.Temperature, value);
    if (temperature != v)
    {
      temperature = v;
      Changed("SystemTemperature");
      Changed("UserTemperature");
    }
  }
}

Sí, claro. Solo tenga cuidado de verificar NULL antes de aplicar cualquier método (como trim ()).

Hay dos escuelas: una dice que está bien verificar los parámetros en setter (estilo escolar) y la segunda dice que los beans no deben contener ninguna lógica y solo datos (estilo empresarial).

Creo más en el segundo. ¿Con qué frecuencia observa la implementación de sus beans? ¿debería getUser lanzar alguna excepción o simplemente devolver nulo?

Cuando pones lógica en tu setter y getters, haces más difícil entender qué está pasando, ya que muchas personas nunca verán su implementación. Si no está de acuerdo, le insto a que observe cada implementación de setter y getter antes de usarla solo para verificar si no es solo un bean.

A primera vista parece que viola el principio del mínimo asombro . Si soy un usuario de tu clase, esperaría que un setter haga exactamente lo que le digo. Lanzaría una excepción en el setter para obligar a los usuarios a recortar la entrada.

La otra alternativa (¿mejor?) es cambiar el nombre del método a trimAndSetString. De esa manera, no es un comportamiento sorprendente recortar la entrada.

Corrígeme si me equivoco, pero me parece lógico que el setter deba mantener este tipo de lógica. Si el setter solo está asignando algún valor a un var interno sin verificarlo, entonces ¿por qué no exponer el var mismo?

Esta es exactamente la razón por la que usa setters en lugar de exponer los campos de objetos a todo el mundo.

Considere una clase que tiene un ángulo entero que se espera que esté entre 0 y 359 inclusive.

Si expone el campo, las funciones de llamada pueden establecerlo en lo que quieran y esto rompería el contrato especificado por su API. También es probable que rompa su funcionalidad en algún lugar del camino porque su código está escrito para asumir un cierto rango para esa variable.

Con un setter, hay varias cosas que puedes hacer. Una es plantear una excepción para indicar que se pasó un valor no válido, pero eso sería incorrecto en mi opinión (para este caso). Es probable que sea más útil si modifica el valor de entrada a algo entre 0 y 359, como con:

actualVal = passedValue % 360;

Mientras esto se especifique en su interfaz (API), es perfectamente válido. De hecho, incluso si no lo especifica, aún puede hacer lo que quiera, ya que la persona que llama ha violado el contrato (al pasar un valor fuera del rango). Tiendo a seguir la regla de "desinfectar su opinión lo antes posible".

En su caso específico, siempre que especifique que la cadena se almacena en formato recortado, no hay motivo para que las personas que llaman se quejen (ya ha declarado que dicha cadena no es válida). Es mejor en términos de tamaño de código (no de velocidad) hacerlo en el setter en lugar de en cada pieza de código que llama al setter. También garantiza que la cadena se almacene como espera que esté; no hay garantía de que una persona que llama no almacene accidentalmente (o intencionalmente) una cadena no recortada.

Sí Una característica del diseño orientado a objetos es que la persona que llama puede tratar su clase como un cuadro negro. Lo que haces dentro es tu propio negocio, siempre y cuando el comportamiento de la interfaz esté documentado y sea lógico.

Si bien diferentes personas tienen diferentes filosofías, sugeriría que los establecedores de propiedades solo sean apropiados en los casos en que establecerán un aspecto del estado del objeto para que coincida con el valor indicado y tal vez notifiquen a alguien que se preocupe por el cambio, pero no lo harán. de lo contrario, afectará el estado del objeto (es completamente apropiado que un establecedor de propiedades cambie el valor de una propiedad solo lectura si esa propiedad se define en términos del estado asociado con el establecedor de propiedades; por ejemplo, La propiedad Right de solo lectura de un control puede definirse en términos de sus Bounds ). Los establecedores de propiedades deberían lanzar una excepción si no pueden realizar la operación indicada.

Si se desea permitir que un cliente modifique el estado de un objeto de alguna manera que no cumpla con la descripción anterior, se debe usar un método en lugar de una propiedad. Si se llama a Foo.SetAngle (500) , sería razonable esperar que el método utilice el parámetro indicado para establecer el ángulo, pero la propiedad Angle podría no devolver el ángulo en la misma forma en que se configuró (por ejemplo, podría devolver 140). Por otro lado, si Angle es una propiedad de lectura y escritura, uno esperaría que escribir un valor de 500 estaría prohibido o de lo contrario haría que el valor volviera a leer 500. Si uno quisiera tener el objeto almacena un ángulo en el rango de 0 a 359, el objeto también podría tener una propiedad de solo lectura llamada BaseAngle que siempre devolverá un ángulo en esa forma.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top