Pregunta

Teniendo en cuenta la definición de clase a continuación. ¿Cómo uno va sobre decidir si los métodos de derivación deben ser estáticos o no estático?

class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // Should the methods add(), subtract() and inverseOf() be non-static ...

    public Point add(Point point) {

    }

    public Point subtract(Point point) {

    }

    public Point inverseOf() {

    }


    // Or static?

    public static Point add(Point point1, Point point2) {

    }

    public static Point subtract(Point point1, Point point2) {

    }

    public static Point inverseOf(Point point) {

    }
}
¿Fue útil?

Solución

Me iría por los métodos de instancia. A continuación, tiene la capacidad de hacer la parte de un inteface métodos y anularlos. Se podría obtener el beneficio cuando se tiene que tratar con puntos 2d o 3d puntos y pasar un buen código de cliente que realmente no importa y sólo tiene que realizar operaciones en los puntos de aplicación de la interfaz.

Otros consejos

creo que depende de lo que está tratando de lograr. Si va a proporcionar un método que añade dos puntos juntos, entonces usted quiere un método estático. Pero si quieres un método que añade un punto a un punto dado ejemplo a continuación, desea un método no estático.

Si usted hace uso de unos métodos estáticos, entonces usted podría considerar la posibilidad de los métodos estáticos en una clase de utilidad independiente (PointCalculator) que sólo contiene métodos estáticos. Esto es similar a la clase de matemáticas.

Me gustaría ir para los métodos no estáticos que son más orientado a objetos (sí, el uso de demasiados método estático se rompe el beneficio de objetos como polimorfismo, herencia ...), incluso si su Point es inmutable. Y, de hecho, esto sería coherente con la forma en clases como BigDecimal o BigInteger están diseñados. Además de eso, métodos estáticos hacen clases más difíciles a prueba de así que prefiero evitar su uso si es posible, sobre todo cuando tiene sentido.

Semánticamente, el enfoque estático parece tener un poco más de sentido. Tanto voluntad de trabajo del curso, pero el enfoque no estático da preferencia a un punto sobre otro, y además implica que el Punto 1 (el método que se llama add on) pueden ser modificados como resultado de la llamada.

Como desarrollador usando sus clases, si vi lo siguiente:

Point p1 = new Point(1,2);
Point p2 = new Point(2,3);

p1.Add(p2);

o ..

Point p1 = new Point(1,2);
Point p2 = new Point(2,3);

Point.Add(p1, p2);

mi inclinación natural sería suponer que el método add () en la versión modifica no estáticos Point1 añadir el resultado del punto 2. Con el enfoque estático, es más clara (aunque no garantizada!) Que el método es puro y los puntos represenative no están siendo modificados.

Uso de un método estático cuando el cuerpo del método no depende de cualquier instancia particular.

Como un ejemplo, miren tu método add(Point, Point). Está añadiendo juntos los dos Points que se pasan a la función como argumentos, y volviendo otra Point. ¿Esto realmente necesita una referencia interna para this algunos Point?

Por otro lado, tiene una add(Point) método. Presumiblemente esto se suma el argumento de la función a la instancia -. En ese caso, tendría que hacer este método de una instancia para que tenga ambas Points

Editar : Creo que no he entendido bien, en un principio. Mirando hacia atrás, tiene las firmas correctas para las implementaciones tanto la estáticos y no estáticos. En este punto, yo diría que es una cuestión de estilo, como saben tanto funcionará correctamente. ¿Cómo quiere que su clase de punto que se utilizará? Piense si se hace que el código sea más intuitivo que decir Point a = Point.add(b, c) o Point a = b.add(c). Personalmente, como el anterior, ya que me dice que va a ser modificado ninguno de los operandos.

Si va a utilizar Java y crear objetos, a continuación, estilísticamente, creo que debería tratar de hacer el máximo uso de los objetos y la encapsulación de datos. Para mí, eso significa que salen de los datos donde está (en la clase Point) y no pasan a un método separado para tratar con él. Haga que sus objetos de trabajo para usted; no sólo tienen captadores y definidores. De hecho, pensar seriamente en cómo se puede evitar la necesidad de un captador en absoluto.

Es perfectamente normal tener métodos como add () y restar () en una clase inmutable que volver nuevas instancias de la clase inmutable. Este es un buen estilo para la programación FP-como y perfectamente razonable para una clase como esta. (. Ver BigInteger o BigDecimal para los buenos ejemplos no ven fecha o calendario para los malos ejemplos de miedo roto:.)

Mantener los métodos de la clase le permite definir opcionalmente interfaces que estas clases pueden implementar, utilizar el patrón decorador o el adaptador, escribir ciertos tipos de pruebas, etc.

Me tienden a ir en contra de la norma en esto, pero de cualquier manera me parece razonable.

  • Los métodos, obviamente, debe ser parte del método Point, puesto que tratan específicamente de puntos
  • Para los métodos que utilizan dos puntos, no hay nada en ellos que implican que necesitan más información sobre uno de los puntos que el otro ... Así que no hay presión en cuanto a qué instancia el método sería un miembro no estática de .

En un lenguaje como Java, me gustaría ir con los métodos estáticos, específicamente por el segundo punto por encima. Para un lenguaje que tiene la sobrecarga de operadores (como Ruby), me gustaría ir con un método de instancia para tomar ventaja de eso.

Es natural que estas funciones tiene que ser no estático. Pero si usted duda consulte GRASP, que describen este tipo de cosas.

De acuerdo con GRASP Información Experto estas funciones no debe ser estática.

A pesar de que no hay información directa sobre el método estático, hay

  

Información de expertos nos llevará a   colocar una responsabilidad en clases con   la mayoría de la información necesaria para   cumplirla.

Si usted hace que los métodos estáticos va a mover su lógica más lejos de los datos reales y tendrá que pasar los datos al método.

La eliminación de estática pondrá más cerca de la lógica de datos que utiliza.

Haciéndolos estática también hace que sea más difícil para ellos prueba de la unidad! El marco sólo se burla Soy consciente de .NET en que podría manejar esto es Typemock.

Si la intención es hacer de esta clase inmutable, de lo que va a regresar objetos nuevo punto de acceso en cualquiera, llamada así haciéndolos estático no tiene mucho sentido aquí.

Estos métodos deben ser estático porque la propia clase se presta a ser creado a través del constructor y los valores de una vez debido a X e Y siendo final asignada. Esto significa que puede crear puntos, pero no manipular sus datos en el futuro. Agregar / Restar / etc, son métodos de utilidad que no debería requerir una instancia de punto a utilizar métodos.

En su caso, tiene que ser no estática a menos que cambie la firma a public static Point add(Point point1, Point point2).

Editar : Me puse votado. Esta bien. No estaba tratando de dar la sugerencia triviales como poner estática en el método frontal. En este caso, un método de instancia es mejor, pero realmente no hay respuesta de la chamusquina. Sólo depende de su preferencia.

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