Otra dudita de Java :D

PiPePiTo

Programad una navaja en Java y luchad!

Luchad! Luchad! Luchad!

1 1 respuesta
NoRelaX

#31 Será una najava

3 1 respuesta
pantocreitor

#32

2
amfro

Luego en el mundo laboral apenas usarás el switch para nada :joy::joy: :joy::joy::joy::joy::joy::joy::joy: :joy::joy::joy:

1 respuesta
pirobiro

#22

Hace falta tener Netbeans si o sí? El curso que estaba haciendo estabamos sobre todocon eclipse y visual studio...

1 respuesta
B

#35 NetBeans o IntelliJ, si usas el primero, mejor que mejor. También parece ser que está el plugin para VSCode (https://www.mooc.fi/en/installation/vscode#installing-vscode) pero no te puedo decir qué tal funciona porque no uso ese editor.

Por otro lado te diría que te olvides un poco de Eclipse (más allá de usarlo si te lo piden expresamente en curso), porque se ha quedado ya bastante outdated.

2 respuestas
pirobiro

#36

En el curso estamos con Eclipse si,además cuando empezé a mirar estas cosas vi que pildoras informaticas también lo usaba,pero bueno, bueno saberlo, iré cacharreando sobre otros...

Al final instalé el NetBeans y me dio otro error ya que el profesor es un poco de la vieja escuela parece ser y el java que nos recomendó instalar para el curso noes superior al 1.8 y al menos para acabar con el curso seguiré con esto

1 respuesta
BaRtoZ

#37 Java 8 está bien, no necesitas más para aprender. Dudo que llegues a expresiones lambda, así que te valdría con Java 7, para que te hagas a la idea..

#36 Yo amo IntelliJ. Me quitan ese IDE y me muero xD

2 respuestas
SupermaN_CK

#38 Pero para la versión buena de IntelliJ hay que pagar, no?

1 respuesta
BaRtoZ

#39 No he pagado nunca y no he necesitado hacerlo.

También es verdad que yo programo en Java, Scala, Bash y Groovy. Así que me viene de perlas.

B

Puedo dar fe de que Java funciona perfecto en VSCode. Tienes el Java Extension Pack en la sección de extensiones que te instala todo lo necesario para hacer de VSCode un IDE que poco tiene que envidiar a los habituales. Empecé con Eclipse como la mayoría supongo, pero fue probar VSCode con Java y me enamoré de lo ligero que es y todas las configuraciones que le puedes meter + las combinaciones de teclas por defecto, que te dan la vida. Los problemas que te puedas encontrar serían mucho más adelante, que por ejemplo para Maven tiene soporte total pero para Gradle tienes que tirar de repos externos para buscar los paquetes, pero para lo que es picar código y aprender, de lujo. Lo bueno es que es un editor que puedes usar con varios lenguajes y tanto para back como para front, de tal forma que no tienes que andar cambiando constantemente y trabajar en un entorno conocido se agradece.

EDIT: Por no hablar de los snippets, que te facilitan la vida hasta niveles insospechados. Este por ejemplo lo fui mejorando a medida que iba avanzando en un proyecto personal y ahora mismo, literalmente, podría hacer una API Rest en 10 minutos.
Lo metes en C:\Users<Usuario>\AppData\Roaming\Code\User\snippets y luego en cualquier documento de tipo .java escribes "spring-" y el asistente de autocompletado hace el resto.

spoiler
isvidal

#34 wat

1 respuesta
pirobiro

#38

No,no lo creo, o eso espero, porque en un curso tan corto, espero que no nos den mucho o eso espero que los cimientos los completen bastante bien y no intenten dar teoría por darla,y que al final "me suene" todo pero no sepa ni hacer lo que estoy intentando ahora que es crear arrays con números primos aleatorios,del 1 al 100 y no repetidos y ya me estoy desesperando.... xD

1 respuesta
B

#43 Para esos problemas no te queda más remedio que recorrer los valores que ya hayas guardado donde quiera que los hayas guardado. No sé cuánto apreciarás a tu profe, pero leyendo lo que has escrito sobre el SDK y el IDE, úsale para hacerte una idea de lo que te falta por aprender para saber qué ignoras y búscalo por tu cuenta, porque lo que te enseñe será arcaico. Btw para lo que estás haciendo hay una estructura de datos específica que son los HashSets. Échales un ojo.

JuAn4k4

intelliJ es gratuito para estudiantes, necesitas correo de Universidad creo

Kaledros

La versión Community de IntelliJ es gratis pero está limitada: https://www.jetbrains.com/idea/features/editions_comparison_matrix.html Para aprender te sobra, pero para cualquier cosa más te va a faltar de todo.

Y sí, puedes usar VSC, pero no es un estándar y te estarías acostumbrando al equivalente de llevar un coche inglés en una carretera española.

13 días después
Flashk

#42 Existen patrones de diseño que permiten obviar casi totalmente la necesidad de un switch.

2 respuestas
JuAn4k4

#47 He visto switches de 100 cases.

1 respuesta
frekaice

#47 Cuéntaselo a este: https://github.com/TerryCavanagh/VVVVVV/blob/master/desktop_version/src/Game.cpp#L731

1 respuesta
Flashk

#48 #49 y? No he negado que existan switches grandes, solo he señalado que existen alternativas a hacer un código espagueti larguísimo y farragoso de entender a través de patrones, como por ejemplo, Strategy Pattern.

Por ejemplo, en el caso concreto del repositorio que ha puesto #49:
Se ve que en ese caso, el switch es básicamente una máquina de estados dentro del juego. En ese caso sería aplicable usar State Pattern (una variante de Strategy).

Obviamente, refactorizar un switch tan grande llevaría bastante rato y no sería fácil ni rápido de hacer, no lo voy a negar. Esto es así es porque se ha vulnerado totalmente el principio DRY (Don't Repeat Yourself) y algunos principios de refactorización (Refactory early, Refactor often, Three Strikes and you Refactor).

Un switch está bien para cosas pequeñas, pero en el momento en el que veas que un switch (o ya de manera general, cualquier código) empieza a ser repetitivo, hay que refactorizar.

Sitios web y lecturas recomendadas.

3 respuestas
JuAn4k4

#50 Si, pero los va a usar.

1 respuesta
desu

#50 Como funciona entonces?

Si no escribes el switch como sabe tu código que le toca compilar (o generar bytecode) o que ejecutar en runtime?

Veo que hablas de Java, como implementa java el dynamic dispatch?

1 respuesta
Flashk

#51 alguien dijo que no? Me autocito:

Un switch está bien para cosas pequeñas, pero en el momento en el que veas que un switch (o ya de manera general, cualquier código) empieza a ser repetitivo, hay que refactorizar.

Flashk

#52 No se quita el switch y funciona por arte de magia, claro está. Lo que se hace es sustituir dicho switch por una serie de clases, cada una con su propia responsabilidad. Es decir, usas el polimorfismo de la POO a tu favor para resolver el problema.

Por poner un ejemplo, hay uno muy bueno en el libro de Refactoring, no voy a copiar el código, solo explicarlo:

  • Inicialmente tiene una clase Movie, que tiene un método getCharge que recibe por parámetro un entero con el total de días que se ha alquilado. Internamente, el método tiene un switch para establecer que precio devolver de la película en función los días que la has alquilado y de si es una peli recién estrenada, una peli ya antigua o una peli para niños.
  • Tras analizar el método, determina que el método getCharge de Movie, se puede extraer a una clase aparte Price, y a continuación, crea subclases de Price para los diferentes tipos de precios RegularPrice, ChildrenPrice y NewReleasePrice; cada una de estas clases calculan el precio de una forma diferente (es decir, cada una tiene el código que antes estaba puesto en cada case del switch).
  • De esta forma, ya no es la clase Movie la que tiene un switch y dice (si soy una película nueva, devuelvo tanto, y si soy una película vieja, devuelvo cuanto). La clase Movie tiene un Price, a quién delega la responsabilidad de calcular su precio. Y como tenemos polimorfismo, podemos asignar a la película cualquier tipo de precio que herede de Price.
  • Si en un futuro queremos crear más tipos de precios, ni siquiera tenemos que tocar ya el código de la clase Movie.

El Strategy Pattern es dinámico en tiempo de ejecución (como muchos otros patrones de comportamiento).
Si hoy añado a mi catálogo de películas una nueva película, entonces podría hacer:

Movie myMovie = new Movie();
myMovie.setPrice(new NewReleasePrice());
...

Pasados unos meses, podría decidir cambiar el tipo de precio:

Movie movie = [... obtengo la película de bbdd ...];
movie.setPrice(new RegularPrice());

También tienes ejemplos con código en los enlaces de Baeldung que dejé en #50

Sobre tu pregunta de como implementa java el dynamic dispatch, ni idea. No sé todos los entresijos de java, y cuanto más sé, más me doy cuenta de que hay mucho más por aprender ahí fuera.

1 respuesta
desu

#53 Para empezar si estas haciendo OOP si es una peli nueva, regular o de ni;os debería ser una característica de la película, no del precio. Que lo puedes hacer con un field tipo o con una jerarquia si quieres ser OOPy.

class Movie {
  MovieType type;
}

vs

class RegularMovie {}
class NewMovie {}
class ChildMovie {}

De esta manera ni siquiera necesitas ningún patrón estrategia porque tienes una interficie "computePrice" para todas tus peliculas. Y cada vez que creas una película sabes como computar el precio. Si una película cambia su tipología en el futuro, tan solo tienes que actualizar la referencia.

interface implementes ComputablePrice  {
  int computePrice(int days);
}
class RegularMovie implementes ComputablePrice {}
class NewMovie implementes ComputablePrice  {}
class ChildMovie implementes ComputablePrice {}

Por que no usas la interficie? Por que lo pones dentro de Price y acoplas el precio con características de la película?

1 respuesta
isvidal

#50 KISS >>>>>>>>>>>> DRY

1 respuesta
Flashk

#54 Es importante distinguir cuando hay que usar herencia y cuando composición.
Tu solución tiene un problema: estás diciendo que "una película ES un precio de alquiler" (herencia), cuando en realidad es que "una película TIENE un precio de alquiler" (composición).

Entonces, con tu código, si creas una película, por ejemplo Jurassic Park, en el momento de su estreno, harías lo siguiente:

ComputablePrice jurassicPark = new NewReleaseMovie();

Por lo que al ejecutar jurassicPark.computePrice() te dará el precio de una nueva release.

Pasan unos meses y la película deja de ser novedad. ¿Qué ocurre?
Ya no puedes calcular su precio, porque has dicho que jurassicPark es una película de tipo "NewReleaseMovie". Has acoplado el precio a la película. Para cambiar su precio tendrías que crear la peli de nuevo y copiar todos sus atributos de un lado a otro.

El patrón Strategy resuelve eso, no acoplas el precio a la película por herencia, sino que permites cambiar el precio usando composición.

En primer lugar, tienes tres clases de precios y una interfaz, de manera similar a lo que tú has hecho, solo que diciendo que en realidad son precios, en lugar de películas:

interface implementes Price  {
  double computePrice(int days);
}

class RegularPrice implements Price
{
	double computePrice(int days) {
		double result = 2;
		if (daysRented > 2)
			result += (daysRented - 2) * 1.5;
		return result;
	}
}

class NewReleasePrice implements Price  {
	double computePrice(int days) {
		return (daysRented > 1) ? 2: 1;
	}
}

class ChildrensPrice implements Price {
	double computePrice(int days) {
	double result = 1.5;
	if (daysRented > 2)
		result += (daysRented - 3) * 1.5;
	return result;
	}
}
class Movie {
	Price price;

double computePrice(int days) {
	return price.computePrice(days);
}

void setPrice(Price price) {
	this.price =price;
}
}

Ahora el precio es una parte de una película, en lugar de ser la película en si, por lo que puedo cambiar de manera dinámica el tipo de precio que tiene la película que creamos previamente:

Movie jurassicPark = new Movie();
jurassicPark.setPrice(new NewReleasePrice());
jurassicPark.computePrice(4); // Se calculará el precio como una nueva película

// Ahora decido cambiar el precio de la película:
jurassicPark.setPrice(new RegularPrice());
jurassicPark.computePrice(4); // Se calculará el precio como una película normal.

Los patrones de diseño buscan precisamente un bajo acoplamiento y una alta cohesión. La herencia suele aumentar el acoplamiento, no disminuirlo, hay que usarla con cuidado, eligiendo bien donde aplica tener herencia y sobre qué la vas a aplicar.

#55 KISS y DRY no son incompatibles entre si.
La dificultad estriba en encontrar un equilibrio entre ambos. Tu código no debería tener duplicidades innecesarias porque dificultan la mantenibilidad, pero tampoco deberías procurarte por refactorizar cosas que todavía no necesitan una refactorización. Además, si la refactorización es buena, tu código puede que pase a tener más clases, pero el código en cada una de ellas será más sencillo, por lo que se validaría el principio KISS.

2 respuestas
eondev

#56 Menuda pereza de código. Yo añadiría una clase dinero, y subclases que fuesen la moneda, rollo euro dólar etc. También haría una clase que marcase el valor en cada momento, así según le asignes el precio en euros o dólares se calcula gracias a ess clase. Así queda más claro.

1 respuesta
Flashk

#57 tú ríete, pero de hecho Martín Fowler define un patrón en su libro para modelar eso mismo que dices:
https://martinfowler.com/eaaCatalog/money.html

Kaledros

¡Han cantado bingo!

desu

#56 He simplificado tu codigo, me he cargado 1 interficie y 3 subclases que no aportaban nada y los he puesto a nivel de entidad. Si creas una jerarquia de Price tambien puedes crear una jerarquia de Peliculas.

#56Flashk:

Pasan unos meses y la película deja de ser novedad. ¿Qué ocurre?
Ya no puedes calcular su precio, porque has dicho que jurassicPark es una película de tipo "NewReleaseMovie". Has acoplado el precio a la película. Para cambiar su precio tendrías que crear la peli de nuevo y copiar todos sus atributos de un lado a otro.

Que problema hay en cambiar la referencia de pelicula a cambiar la referencia del Price? En ambos casos requeriras hacer un cambio. Tu cambias el precio, yo re hago una pelicula porque la pelicula ha pasado de ser estreno a para ni;os. Lo que cambia conceptualmente es la pelicula.

movie.setPrice(new RegularPrice());

Tu mismo lo dices, la PELICULA deja de ser novedad.

#56Flashk:

Pasan unos meses y la película deja de ser novedad. ¿Qué ocurre?

Conceptualmente lo que ha cambiado es la pelicula.

Igualmente, vamos a aceptar que quieres separar la pelicula del precio. Aunque no me has convencido demasiado, cambias el nombre y escribes 4 veces mas código para tener que mutar las referencias cuando una película (no el precio) cambie de tipología. Ok.

Ahora vamos a poner ademas el caso mas variable de todos, las películas cambian de tipología y ademas el precio de una novedad depende de la pelicula o de un factor externo. Si el precio de RegularPrice cambia y este depende de la pelicula como lo modificas?

1 1 respuesta