Perdido en C++

elkaoD

#60 pues a mí la notación húngara no me gusta nada de nada porque añade esfuerzo de mantenimiento al cambiar tipos (y enguarrina el código) aparte de que no añade mucha más información que la declaración del tipo (que suele ser obvia, y si no lo es, algo has hecho mal xD)

E.g: Para "finished", "bFinished" no añade información alguna. Ya sé que es un booleano que indica si ha finalizado o no. Sin embargo, me parece que afea el código añadiendo ruido innecesario.

Obviamente hay casos en los que sí es útil, pero no lo llamaría notación húngara, lo llamaría "añadir completitud al nombre de la variable para que sea más obvio qué es". La notación húngara "por obligación" es una guarrada.

Por ejemplo, si tengo un "Car current;" y no es obvio que "current" sea un "Car" le llamo "Car currentCar;". Sin embargo, si estoy en una rutina que trata con "Car" y sólo con "Car", me sobra y basta con llamarle "current".

1 respuesta
BLZKZ

#59 pero no solo en lips, con haskell tampoco programo como con c++, pero aqui se habla de c++ no de lisp, clojure o haskell xDDD

#63 xDDDDDDD

1 respuesta
elkaoD

#62 ah, que este hilo va de C++? Creí que estábamos en el de estilo de código xD

1 respuesta
B

#61 si, pero es la costumbre y te da 2 puntos de carisma usarla.

<troll>Pues yo uso goto que pasa! </troll>

1 respuesta
eisenfaust

#57 Depende, cuando programo en Lisp o Perl por poner un ejemplo rara vez suelo poner algún comentario ya que son lenguajes muy expresivos y generalmente con un simple stringdoc sobra.

Pero cuando lo que escribes es algo como esto:

qks:{f:*x@1?#x;:[0=#x;x;,/(f x@&x<f;x@&x=f;f x@&x>f)]}

Lógicamente entenderás el que se le preste algo más de dedicación al tener una documentación en condiciones (que en este caso no hace falta porque todo el mundo sabe hacer un quicksort, pero en un entorno real de producción rara vez se suelen ver estos hola-mundos).

De todas formas ten en cuenta que lo que tú consideres como legible o self-documented es altamente subjetivo. Y ahí radica el problema de lo que expones.

#64 Pues yo uso GOTOs para simular TCO en Perl modificando el stack implícito y al que no le guste que no mire xD

1 respuesta
elkaoD

#65 no sé que lenguaje es eso. Me dices que es GolfScript (o APL, J y demás) y me lo creo xD Pero vamos, que es incomparable con C (y primos) que son lenguajes más verbose, y también lo es su cultura. Eso también es importante. Cada comunidad en cada lenguaje tiene un estilo propio que llega a ser tan parte del lenguaje como la sintaxis (y en el caso de muchos está estandarizado en gran medida.)

Me parece que adaptarse a la comunidad ayuda a que la gente que programa en ese lenguaje entienda tu código rápido (y tú el suyo.) Pura convención. También es la razón por la que los bucles for se recorren con la i. Por supuesto, no hay que seguir las reglas a rajatabla (ni siquiera los estándares a lo PEP8 y otras guías de estilo) pero sí que ayuda.

Como curiosidad, la tónica general que he visto en Clojure es ni siquiera añadir docstring si no es un método público. Es decir, las usan sólo para documentar la API. A mí me parece excesivo. Al menos un pequeño docstring es una GRAN facilidad para alguien que llega nuevo al proyecto.

MTX_Anubis

la documentación de código yo pienso que viene dada por la sintaxis del propio lenguaje, lo que permite hacer y los paradigmas que utilice.

En lenguajes como ruby y similares, documentación poca, como mucho poner el por qué lo haces de esa manera y ya está pero algo como esto

villain.kill_them_all unless persons.any? {|p| p.is_a? :hero }

No necesita documentación y como eso la mayor parte del código que vayas a escribir.

Nusep, a mi no me gusta documentar y realmente solo lo hago cuando en alguna parte de mi aplicación hago algo que si no entiendes bien toda la estructura del programa, no entiendes que está haciendo.

1
B

La notación húngara es una putísima mierda. Y esto es objetivo.

2 1 respuesta
B

#68 Usar accessors en POO es una putísima mierda y esto también es objetivo

https://github.com/SantiMunin/Nomasystems-exercise/blob/master/src/es/udc/santiago/data/entities/Company.java

3 respuestas
BLZKZ

#69 lo dices en serio? xD

Supuestamente las bases de la poo apoya el usar acedentes y mutadores xD

#71 getters/setters mejor? xD

2 respuestas
elkaoD

#69 discreparía contigo si no fuera porque el 90% de las veces son innecesarios

Anda que no he visto veces hacer una clase Point con accesores para la "x" y la "y" (típico bean.)

FUCK THE POLICE.

#70 accedentes y mutadores? Suena a panch xD

#70 cogedores y ponedores, de toda la vida xD

1 respuesta
B

#70 me referia a un accesor público, eso rompe la encapsulación de objetos. Deberia existir un método público que no haga referencia a ellos mismos del tipo getData(blablabla),setData(blablabla).

Usar un accesor es tan feo como poner las variables miembros como públicas y acceder a ellas directamente.

2 respuestas
elkaoD

#72 Usar un accesor es tan feo como poner las variables miembros como públicas y acceder a ellas directamente.

Negativo. Lo de usar accesores públicos es para, si en algún momento cambia la implementación interna del objeto, no tener que cambiar también su interfaz (y por tanto romper todo el resto del programa que accedía a los miembros públicos.)

E.g.: ¿qué pasa si en algún momento un miembro de tu objeto deja de existir como tal para pasar a ser un valor calculado? Si tienes el setter/getter puedes cambiar su implementación, no rompes la API, el miembro ya no existe y todo el mundo está contento.

Como un ejemplo rápido: imagina que tienes Persona (¡qué ejemplo más original!) con el campo "int edad" recubierto por un accesor (sin setter.) En algún momento decides dejar de guardar la edad para tener fecha de nacimiento (y calcular la edad con esta.) Si tienes el getter hecho haces que calcule la edad y SANTAS PASCUAS. Sin accesor, al borrar el campo edad romperías todo el código que lo usara como API.

me referia a un accesor público, eso rompe la encapsulación de objetos.
No. No lo hace. Si tienes un setter público es porque necesitas acceder al miembro del objeto de alguna forma. ¿La diferencia? El setter no te permite modificar el valor directamente. Es decir, no te permite "bypassear" el mecanismo impuesto por el objeto.

Con el getter, tres cuartas de lo mismo. Un getter público permite hacer una copia de guarda de los objetos mutables. El acceso público al miembro no.

Por esta razón no se rompe la encapsulación aunque tengas acceso a los miembros internos. Estos quedan encapsulados por sus settergetter.

Deberia existir un método público que no haga referencia a ellos mismos del tipo getData(blablabla),setData(blablabla).
No sé si te he entendido bien. Los objetos tienen miembros de salida, si no tendríamos objetos que sólo interactúan por métodos pero son completamente ciegos a los datos de otros objetos (y si no son ciegos es porque has hecho un accesor, aunque sea más complejo que un simple return... sigue siendo un accesor.)

1 respuesta
B

#73 Negativo. Lo de usar accesores públicos es para, si en algún momento cambia la implementación interna del objeto, no tener que cambiar también su interfaz (y por tanto romper todo el resto del programa que accedía a los miembros públicos.)

Eso solo pasa en los mundos de yupi. En el 99% de las veces vas a tener que cambiar código fuera de ese accesor.

E.g.: ¿qué pasa si en algún momento un miembro de tu objeto deja de existir como tal para pasar a ser un valor calculado? Si tienes el setter/getter puedes cambiar su implementación, no rompes la API, el miembro ya no existe y todo el mundo está contento.

Si no es ya un miembro el médodo que se use no se consideraría accesor pues estaría usando un algoritmo de calculo. Lo mismo soy de marte pero un accesor es un método para acceder a una variable miembro de una clase:

accesor:

getA()
{
return this.a;
}

No es un accesor:
getArea()
{

return calculaArea(blablabal);

}

me referia a un accesor público, eso rompe la encapsulación de objetos.
No. No lo hace. Si tienes un setter público es porque necesitas acceder al miembro del objeto de alguna forma. ¿La diferencia? El setter no te permite modificar el valor directamente. Es decir, no te permite "bypassear" el mecanismo impuesto por el objeto.

El setter no te permite modificarlo directamente?. Que beneficio te da un setA de un objeto.a =?

Deberia existir un método público que no haga referencia a ellos mismos del tipo getData(blablabla),setData(blablabla).
No sé si te he entendido bien. Los objetos tienen miembros de salida, si no tendríamos objetos que sólo interactúan por métodos pero son completamente ciegos a los datos de otros objetos (y si no son ciegos es porque has hecho un accesor, aunque sea más complejo que un simple return... sigue siendo un accesor.)

Te comento lo mismo, para mi un accesor solo lee/escribe la variable miembro, no realiza más operaciones.

2 respuestas
elkaoD

#74 Eso solo pasa en los mundos de yupi. En el 99% de las veces vas a tener que cambiar código fuera de ese accesor.
No. Dame un ejemplo porque no se me ocurre ninguno. En el 99% de los casos, si la propiedad de la clase sigue teniendo sentido (es decir, si sigue siendo lógico tener un getter/setter) te basta con cambiar la implementación para no romper nada, hagas lo que hagas con el miembro. Es la magia de las APIs bien diseñadas.

Si no es ya un miembro el médodo que se use no se consideraría accesor pues estaría usando un algoritmo de calculo.
Pero lo ERA. Es lo importante del accesor, no lo que es ahora sino LO QUE SERÁ EN UN FUTURO. Te permite hacer cambios en la implementación sin romper la API.

Lo mismo soy de marte pero un accesor es un método para acceder a una variable miembro de una clase:
No. Un accesor es un método para acceder a un propiedad de un objeto que puede (o no) ser miembro de la clase. Abstráete. Un miembro de una clase es sólo su implementación, las propiedades de esta son SU API. Una clase es una abstracción y el hecho de que sus propiedades sean miembros o no es un detalle sin importancia alguna.

Pégale una leída http://en.wikipedia.org/wiki/Mutator_method

No puedes decir que el accesor/mutador rompe la encapsulación, cuando precisamente es al contrario. Cito de la Wiki: is most often used in object-oriented programming, in keeping with the principle of encapsulation.

#74 Te comento lo mismo, para mi un accesor solo lee/escribe la variable miembro, no realiza más operaciones.
Pues tienes el concepto equivocado. En efecto, visto así, no tienen sentido los getter/setter, pero es que no son eso. Tienes que distinguir entre el concepto de propiedad y miembro.

BLZKZ

#74 Eso solo pasa en los mundos de yupi. En el 99% de las veces vas a tener que cambiar código fuera de ese accesor.

Si pasa eso es porque tienes mal diseñada la aplicación

2
B

#74 75 El uso de accesors significa una mal diseño.

un ejemplo de objeto bien encapsulado:

#include <iostream>
using namespace std;

class CRectangle {
    int x, y;
  public:
    void set_values (int,int);
    int area () {return (x*y);}
};

void CRectangle::set_values (int a, int b) {
  x = a;
  y = b;
}

int main () {
  CRectangle rect;
  rect.set_values (3,4);
  cout << "area: " << rect.area();
  return 0;
}

Si en vez de set_values usaramos accessors tendriamos dos problemas:

1) tendriamos un accesor por variable = más código a mantener
2) Estamos exponiendo públicamente las variables miembro y va en contra directamente de lso principios de encapsulación.

2 respuestas
elkaoD

#77 si entiendo perfectamente tu punto de vista, pero es que no eres consciente de que los accesores son parte de la API y se dan en los casos en los que son necesarios. Claro que ahí no tienes accesores... ¡porque no son parte de la API! ¿Qué hay si necesitas acceder a X e Y independientemente? ¿Vas a hacerlo sin accesores mediante magia? (hay mil razones por las que querrías conocer sólo la altura del rectángulo.)

Por cierto, set_values es un mutador :) Otra cosa es que Java sea una basura y te toque separar los miembros en dos, pero es un mutador para la propiedad "values" (que a su vez es la agregación de dos miembros.)

Regla de oro: si el método empieza por get es un accesor, si empieza por set un mutador. Me da igual lo que haga o si toca a varios miembros a la vez. Deja de pensar en términos de "accesor a variables" y empieza a pensar en "accesor a propiedades". La POO va de abstraerse y los miembros son sólo un detalle de implementación que en lo que a POO se refiere no significan una puta mierda (excepto si los dejas públicos, en cuyo caso son parte de la API.)

Ahora haz lo mismo con esta clase, es decir, escríbela sin usar accesores. Con un pequeño detalle: la API necesita acceder a los miembros por separado.

class Persona {
    String nombre;
    String primerApellido;
    String segundoApellido;
}

PD: ¿por qué no usas camelCase?

1 respuesta
BLZKZ

#77 de hecho no tiene por qué estar bien lo que has hecho.

Para empezar ese set lo haria en la contructora. Y si quiero cambiar solo la X o (or exclusiva) la Y y no conozco previamente ninguna?

No tienes por qué tener un accesor por variable, sino uno por propiedad que te interese querer cambiar.

No expones publicamente ningún atributo, porque precisamente alguien que solo tiene acceso a la interfaz (API) no tiene ni repajolera de si a lo que accede es a un atributo o es a una formula que los usa.

Estás muy equivocada en concepto, y tratas de generalizar la función de los atributos cuando no son "simples variables" todos.

1 3 respuestas
elkaoD

#79 Y si quiero cambiar solo la X o la Y y no conozco previamente ninguna?

BOOM! Headshot.

Implementación != API. Si tu API no necesita acceder a los miembros por separado por supuesto que no vas a tener accesores.

B

#78 lo del set lo dejé a propósito para indicar que aunque tuviera un set no es un setter. Podrñia ser un constructor como bien dice #79 y no seria un setter. El nombre del método para mi no indica si es un accesor o no. Otra cosa es que por convencionalismo se use o no.

Ahora haz lo mismo con esta clase, es decir, escríbela sin usar accesores. Con un pequeño detalle: la API necesita acceder a los miembros por separado.

Cual es la razón de que la api necesite acceder a un solo campo de los datos de una persona?.

2 respuestas
cabron

#81

Un caso real que utiliza lo mismo que has puesto como ejemplo, un rectángulo:

Yo utilizo una librería gráfica para dibujar y otra librería para las simulaciones físicas. La librería gráfica trabaja en píxels, la librería física en m.

Yo decido la relación entre pixels y metros, si quiero que un pixel equivalga a 5m, cuando creo un objeto en el simulador físico, le tengo que dar el tamaño correspondiente al tamaño en pixels, para que las colisiones coincidan con lo que el jugador ve.

Puesto que no sé de antemano cuantos pixels miden todos los sprites que se van a cargar, tengo que hacer:
anchoObjeto = sprite.obtAncho() / RATIO_PIXELS_METROS
altoObjeto = sprite.obtAltio() / RATIO_PIXELS_METROS

Si los que hicieron la libreria gráfica, no hubiesen puesto la capacidad de acceder por separado al alto y al ancho de un sprite (que no deja de ser un rectángulo) explícame como coño lo hago.

1 respuesta
elkaoD

#81 lo del set lo dejé a propósito para indicar que aunque tuviera un set no es un setter.
Pero es que ES un setter.

Podrría ser un constructor como bien dice #79 y no seria un setter.
Y si mi abuela tuviera ruedas sería un bicicleta. Claro que si lo pones en el constructor no es un setter xD

Cual es la razón de que la api necesite acceder a un solo campo de los datos de una persona?.

Era un ejercicio mental pero bueno, si quieres me lo invento: para sacar estadísticas del nombre más común en un país, por ejemplo.

No vale concatenar y des-concatenar luego, imagina nombres como "Felipe Juan Froilán de Todos los Santos de Marichalar de Borbón". Necesito el nombre y apellidos por separado.

1 respuesta
B

#82 Probablemente tendria algún método del tipo getsize() si no quisieran usar accessor.

#83 .cargaDatos() que te devuelva los datos del usuario y luego lo parseas como te venga en gana. Evidentemente si lo llevas al extremo de "me tiene que dar solo apellidos por cojones" no te queda otra que acceder mediante accessor.

1 respuesta
cabron

#84

¿y que valor me devolvería ese método getSize()? Pon un ejemplo con churricódigo igual que he hecho yo.

1 respuesta
B

#85 array(x,y)

cabron

#85

juaaaaaas, creo que estás llevando está discusión al absurdo... vamos que según tú devolver un array con los valores x e y, es un diseño correcto, mientras que devolver por separado los valores x e y es una aberración, además que tu getSize() por el hecho de devolver los dos valores a la vez, ya deja de ser un accesor????

Según tu ejemplo al final tendría que hacer esto:

anchoObjeto = sprite.getSize()[0] / RATIO_PIXELS_METROS
altoObjeto = sprite.getSize()[1] / RATIO_PIXELS_METROS

Que viene a ser exactamente lo mismo.

1 respuesta
B

#87 Es que en el sentido estricto no es un accesor.

1 respuesta
BLZKZ

#88 ???? entonces cual es el sentido que tu le das? porque debes ser única XD

y desde luego devolver un array en ese caso es caca de la vaca xD

1 respuesta
B

#89 Estrictamente hablando, unn accessor devuelve/setea una sola variable miembro del objeto PUNTO.

1 respuesta

Usuarios habituales