Seguimos buscando a Arshak. Ayudanos compartiendo!
Encuesta no oficial de docentes
Resultados de la encuesta no oficial de docentes
Probaste el SIGA Helper?

Donar $100 Donar $200 Donar $500 Donar mensualmente


Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Buscar en el tema
[FINAL][2015/07/18] Resolución
Autor Mensaje
leandrong Sin conexión
Secretario de la SAE
...
******

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 632
Agradecimientos dados: 180
Agradecimientos: 616 en 80 posts
Registro en: Sep 2008
Mensaje: #1
[FINAL][2015/07/18] Resolución Finales Diseño de Sistemas
Gente:
Estoy intentando realizar el final del 18/07/2015 de Diseño de Sistemas.

Importador (18-07-2015)

Si alguien me puede dar una mano con esto, se los agradecería!

Diseño en Objetos
Spoiler: Mostrar

   

Por lo datos del enunciado, se observa que cada Producto tiene su impuesto propio, por lo que no es necesario crear una clase para que solo tenga el valor del porcentaje. Podría tenerse una clase si muchos productos dependiesen de un porcentaje que pueda variar, y al modificarse se modificaría en todos, pero el enunciado no lo dice.

Lo que sí diferencia a los objetos son los tipos de recargos que pueden tener (ser suntuario, tener sustituto local, o en el futuro agregarse un nuevo recargo).

Una solución alternativa es que cada producto tenga una lista de recargos, y que cada recargo sepa cómo calcular ese valor extra. Cada clase Recargo tendría sus atributos que pueden modificarse sin necesidad de tocar el código ya que pueden modificarse en tiempo de ejecución.

En la solución mencionada se utilizó el Patrón Decorator.
Por ejemplo, si tengo un TV80 que es suntuario y además

ProductoConcreto tv80 = new ProductoConcreto
ProductoConImpuesto pci = new ProductoConImpuesto
ProductoSuntuario ps = new ProductoSuntuario

Seteamos los productos para ir agregando los impuestos.
pci.producto(tv80)
ps.producto(pci)

Para calcular el precio de venta:
ps.precioVenta()

Lo que es igual a
pci.precioVenta() * impuesto = //Supongamos 0.05 el impuesto
= (tv80.precio(venta) * 0.05) * 3000 =
= ((2 * costo)) * 0.05) * 3000. //Supongamos el costo de la TV 6000
= (2 * 6000)) * 0.05) * 3000)
= 1.800.000

Como se ve el valor calculado no tiene coherencia y esto se debe a:

• Hay un error en cómo se calcula el precio de venta para el producto concreto ya que lo realiza mediante “2 * costo” y el enunciado dice el 100% del costo.

• Hay un error en el método “precioVenta()” de la clase Abstracta “ProductoConRecargo” (precio de venta * el impuesto). Si bien en el caso de Producto con impuesto se calcula bien, para el caso de suntuario lo tendría que sumar (ejemplo: 10000 + 3000, y no 10000 * 3000).

Además de calcular mal el precio de venta, es difícil agregar y quitar impuestos una vez que se creó el producto, ya que es necesario saber cuál es el producto que lo tiene como atributo y si este a su vez es atributo de otro recargo.

En la nueva solución, el precio de venta lo calcula el Producto teniendo en cuenta el costo, el impuesto y los recargos que tiene. De esta manera si se crea un nuevo recargo, solamente es necesario crear la clase.
Se pueden quitar o agregar recargos existentes a un producto de forma dinámica simplemente con agregarlos o quitarlos de su lista de recargos.

En cuanto a la cohesión del objeto Producto, aumenta ya que tiene bien definida la responsabilidad de calcular el precio de venta, cuando antes se calculaba separadamente por distintas clases.

Sobre exenciones impositivas no queda claro si se descontaría del precio de venta o si infiere en el costo del mismo. Supongo que es un recargo más.


Código en Xtend
Spoiler: Mostrar

class Producto
{
var String nombre;
var double impuesto;
var double costo;
var List<Recargo> recargos = newArrayList;

new (String unNombre, double unCosto, double unImpuesto)
{
this.nombre = unNombre;
this.costo = unCosto;
this.impuesto = unImpuesto;
}

def double precioVenta()
{
return (this.costo + this.calcularImpuesto() + this.calcularRecargos())
}

def double calcularImpuesto()
{
return this.costo * impuesto;
}

def double calcularRecargos()
{
return this.recargos.map[obj | obj.calcularRecargo(this)].reduce[sum, obj | sum + obj];
}

}

interface Recargo
{
def double calcularRecargo(Producto unProducto)
}


class Suntuario implements Recargo
{
var int valorExtra;

new (int unValorExtra)
{
this.valorExtra = unValorExtra;
}

override double calcularRecargo(Producto unProducto)
{
return valorExtra;
}
}

class SustitutoNacional implements Recargo
{
var double porMin; //Porcentaje Mínimo
var double porMax; //Porcentaje Máximo
var int valor;

new (int unValor, double unPorMin, double unPorMax)
{
this.valor = unValor;
this.porMax = unPorMax;
this.porMin = unPorMin;
}

override double calcularRecargo(Producto unProducto)
{
if (unProducto.costo > valor)
{
return unProducto.costo * this.porMax;
}

return unProducto.costo * this.porMin;
}
}

class MainClass
{
def public static void main(String[] args)
{
var Producto producto = new Producto("Auto",30000,0.5);
var Suntuario suntuario = new Suntuario(3000);
var SustitutoNacional susNac = new SustitutoNacional(10000,0.05,0.10);

producto.recargos.add(suntuario);
producto.recargos.add(susNac);

println(producto.precioVenta());
//Imprime 51000 (30000 + 15000 + 3000 + 3000)
}
}


Arquitectura
Spoiler: Mostrar
En cuanto a la persistencia, es más fácil guardar información de un producto y sus recargos si este los tiene en una lista, en vez de que cada recargo conozca solamente a otro recargo o finalmente a otro producto.

Ejemplo:
Recargo2 -> Recargo1 -> Producto

Mi solución:
Producto: [Recargo1, Recargo2]

Y en cuanto a la interfaz del usuario, el manejo de eventos y binding de datos es más fácil ya que los realiza directamente el producto, por ejemplo, para el cálculo del precio de venta es quién tiene la responsabilidad de calcularlo. En la solución del enunciado es necesario conocer el último recargo para poder calcular el precio de venta de un producto en particular, lo que hace más difícil manejar este evento.
Otro evento como podría ser el de agregar o quitar recargos, se maneja de forma más fácil ya que es solo agregar o quitarlo de la lista del objeto Producto. En la propuesta del enunciado es necesario modificar los atributos de los recargos.

Metodología y Diseño
Spoiler: Mostrar
Si se utiliza una metodología Ágil, se tiene una metodología:
*Orientada al producto: un producto funcionando es más importante que la documentación exhaustiva
*Orientadas a las personas: las personas y como se relacionan son más importantes que los procesos.
*Iterativa: se divide el proyecto en entregas o iteraciones en las cuales se define un entregable (software testeable por el usuario).
*Adaptativa: se acepta el cambio y error como parte natural del desarrollo.

El cliente forma parte del equipo de trabajo con quién se negocia. Se definen entre todos cuando una tarea está terminada.

En una metodología ágil, con Scrum entre las actividades que se realizan:
Reuniones diarias: no duran más de 15 minutos, se establecen las tareas para las próximas 24 horas y se revisan las tareas desde la última reunión .
Sprint: es el periodo (2-3 semanas) en el que se definen las tareas a llevar a cabo. Al final de este tiempo el equipo se reúne y evalúan las actividades desarrolladas y el resultado es un entregable para el cliente.

Si se utiliza Proceso Unificado, se tiene una metodología:
*Iterativo: e incremental, se divide el trabajo en partes más pequeñas que son iteraciones. Cada iteración amplía el producto.
*Adaptativa: se contempla la posibilidad de modificar los requerimientos hasta la última iteración.
*Persona/Proceso: no está bien definido ya que por un parte considera a las personas importantes y que deben saber qué hacer, pero por otro lado dice que las personas responden a un rol el cual les indica un proceso al cuál seguir.
*Producto/Documentación: se encuentra en la mitad ya que considera que el producto no es solo el software sino también es la documentación: casos de usos, diagrama de clases, diagramas de colaboración, etc.

Cuenta con 4 fases (inicio, elaboración, construcción e implementación) en las que se desarrollan tareas (requerimientos, análisis, diseño, test, configuración, etc) en mayor o menor tarea dependiendo de la fase en la que esté.

Entre las tareas del UP podemos ver en la captura de requerimientos en el cual se realizan casos de usos, actores, reglas de negocios, etc.
El resto de los puntos los voy a agregar después de validar el primero ya que de este depende el resto.
(Este mensaje fue modificado por última vez en: 08-12-2015 22:23 por leandrong.)
07-12-2015 06:36
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] leandrong recibio 2 Gracias por este post
CarooLina (14-01-2016), LAUS (14-01-2019)
guillermoOK Sin conexión
Militante
Sin estado :(
***

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 80
Agradecimientos dados: 26
Agradecimientos: 42 en 20 posts
Registro en: Apr 2015
Mensaje: #2
RE: [FINAL][2015/07/18] Resolución
Yo lo hubiera pensado con un decorator vos lo hiciste con un strategy no?, donde el decorador le va sumando impuestos.

saludos!
07-12-2015 11:19
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] guillermoOK recibio 1 Gracias por este post
CarooLina (14-01-2016)
leandrong Sin conexión
Secretario de la SAE
...
******

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 632
Agradecimientos dados: 180
Agradecimientos: 616 en 80 posts
Registro en: Sep 2008
Mensaje: #3
RE: [FINAL][2015/07/18] Resolución
(07-12-2015 11:19)guillermoOK escribió:  Yo lo hubiera pensado con un decorator vos lo hiciste con un strategy no?, donde el decorador le va sumando impuestos.
saludos!

Ahí modifiqué la justificación porque me di cuenta que había cosas mal.

En realidad no sé si considerarlo Strategy.
En el strategy se elige una estrategia de solución según el objeto.

Interfaz Estrategia tiene el método Algoritmo.
EstrategiaConcretaA redefine el método Algoritmo.
EstrategiaConcretaB redefine el método Algotitmo.
Y luego tengo una clase Contexto que tiene un atributo con 1 de esas clases.
Acá al ser muchas no sé si se lo puede seguir considerando así.

La solución del enunciado, usa el patrón Decorator.

El tema es que en el decorator terminás usando siempre el último decorador concreto y lo que se agregó antes es muy dificil de sacarlo.

// Create ConcreteComponent and two Decorators
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();

// Link decorators
d1.SetComponent( c );
d2.SetComponent( d1 );

Termino utilizando d2 y si quiero en algún momento quiero sacarle d1 es un quilombo.

Por ejemplo, para hacer una hamburguesa con jamón y queso.

ConcreteComponent hamburguesa = new ConcreteComponent();
ConcreteDecoratorA jamon = new ConcreteDecoratorA();
ConcreteDecoratorB queso = new ConcreteDecoratorB();

// Link decorators
jamon.SetComponent( hamburguesa );
queso.SetComponent( jamon);

Y si imprimo quedaría "hamburguesa con jamón y queso".

Patrones Relacionados del Patrón Decorator:
Con el patrón Strategy: el decorador permite cambiar el exterior de un objeto, una estrategia permite cambiar sus tripas (interior).
(Este mensaje fue modificado por última vez en: 07-12-2015 19:57 por leandrong.)
07-12-2015 18:16
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
dalepapa Sin conexión
Profesor del Modulo A
Estado Plasma
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 320
Agradecimientos dados: 190
Agradecimientos: 67 en 45 posts
Registro en: Mar 2015
Mensaje: #4
RE: [FINAL][2015/07/18] Resolución
Hola Leandro! ¿tendrías algún resumen actual de Diseño o algo por el estilo, por favor?
Necesito apuntes teóricos.
Muchas Gracias desde ya!
07-12-2015 23:29
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
leandrong Sin conexión
Secretario de la SAE
...
******

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 632
Agradecimientos dados: 180
Agradecimientos: 616 en 80 posts
Registro en: Sep 2008
Mensaje: #5
RE: [FINAL][2015/07/18] Resolución
(07-12-2015 23:29)dalepapa escribió:  Hola Leandro! ¿tendrías algún resumen actual de Diseño o algo por el estilo, por favor?
Necesito apuntes teóricos.
Muchas Gracias desde ya!

Hola, no, saqué todo de la página

Apuntes, Guías y Papers
08-12-2015 17:19
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Cyphius Sin conexión
Militante
Ing.
***

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 61
Agradecimientos dados: 5
Agradecimientos: 57 en 15 posts
Registro en: Nov 2008
Mensaje: #6
RE: [FINAL][2015/07/18] Resolución
Yo tambien me lo había planteado de la manera con strategy.

Lo unico que me llama atencion de tu codigo (no uso xtend puede ir por ahi el tema) es que apliques map a un list que no entiende map.
Y estoy seguro que aunque entendiere un map para el caso de producto sin impuesto tendrias un run time exception por suma de costo + null al no inicializar el sum en ese caso.
11-12-2015 04:21
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
leandrong Sin conexión
Secretario de la SAE
...
******

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 632
Agradecimientos dados: 180
Agradecimientos: 616 en 80 posts
Registro en: Sep 2008
Mensaje: #7
RE: [FINAL][2015/07/18] Resolución
(11-12-2015 04:21)Cyphius escribió:  Yo tambien me lo había planteado de la manera con strategy.

Lo unico que me llama atencion de tu codigo (no uso xtend puede ir por ahi el tema) es que apliques map a un list que no entiende map.
Y estoy seguro que aunque entendiere un map para el caso de producto sin impuesto tendrias un run time exception por suma de costo + null al no inicializar el sum en ese caso.

return this.recargos.map[obj | obj.calcularRecargo(this)].reduce[sum, obj | sum + obj];

Funciona sin problemas.

En java, queda así

private List<Recargo> recargos = CollectionLiterals.<Recargo>newArrayList();

public double calcularRecargos() {
final Function1<Recargo, Double> _function = (Recargo obj) -> {
return Double.valueOf(obj.calcularRecargo(this));
};
List<Double> _map = ListExtensions.<Recargo, Double>map(this.recargos, _function);
final Function2<Double, Double, Double> _function_1 = (Double sum, Double obj) -> {
return Double.valueOf(DoubleExtensions.operator_plus(sum, obj));
};
return (double) IterableExtensions.<Double>reduce(_map, _function_1);
}
11-12-2015 11:42
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Buscar en el tema
Enviar respuesta 




Usuario(s) navegando en este tema: 1 invitado(s)