• No se han encontrado resultados

Ejercicio de Arquitecturas Software

N/A
N/A
Protected

Academic year: 2021

Share "Ejercicio de Arquitecturas Software"

Copied!
20
0
0

Texto completo

(1)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU 1

Ejercicio de Arquitecturas

Software

Caso de Uso

CONSULTAR PRECIOS

2 import java.awt.*; import java.awt.event.* ;

public class ConsPrecioIU extends Frame { Label label1 = new Label();

Panel panel1 = new Panel(); Button button1 = new Button(); Button button2 = new Button(); Panel panel2 = new Panel();

GridLayout gridLayout1 = new GridLayout(3,2); Label label2 = new Label();

TextField textField1 = new TextField(); Label label3 = new Label();

TextField textField2 = new TextField(); Label label4 = new Label();

TextField textField3 = new TextField(); public ConsPrecioIU() { super(); try { jbInit(); } catch (Exception e) { e.printStackTrace(); } } // Continúa… La interfaz de usuario asociada a un caso de uso llamado CONSULTAR PRECIO aparece a continuación, junto con la clase Java correspondiente :

(2)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

button1.setLabel("Consultar Precio");

button1.addActionListener(new java.awt.event.ActionListener () { public void actionPerformed(ActionEvent e) {

button1_actionPerformed(e); } }); button2.setLabel("Cancelar");

button2.addActionListener(new java.awt.event.ActionListener () { public void actionPerformed(ActionEvent e) {

button2_actionPerformed(e); } }); label2.setText("MANZANAS (Kg.)"); label3.setText("PERAS (Kg.)"); label4.setText("NARANJAS (Kg.)"); panel2.setLayout(gridLayout1); this.add(label1, BorderLayout.NORTH ); this.add(panel1, BorderLayout.SOUTH ); panel1.add(button1, null); panel1.add(button2, null); this.add(panel2, BorderLayout.CENTER ); panel2.add(label2, null); panel2.add(textField1, null); panel2.add(label3, null); panel2.add(textField2, null); panel2.add(label4, null); panel2.add(textField3, null); this.pack(); this.setVisible(true);} void button1_actionPerformed(ActionEvent e) {...} void button2_actionPerformed(ActionEvent e) {...} } 4

Se dispone también de una clase llamada Aviso que sirve para crear Dialog modales asociados al objeto Frame actual. La llamada new Aviso(this,"Pulsa Aceptar y me voy"); crearía lo siguiente :

Además, nos han proporcionado los siguientes métodos, los cuales no sabemos ni a qué clase pertenecen ni qué es lo que hacen exactamente , pero nos han dicho que son útiles para acceder a los datos almacenados e n la siguiente tabla de una BD Access. Además nos dicen que dicha BD es accesible por medio de una fuente de datos ODBC llamada PRODS

(3)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

5

public void inicializarBD () { try {

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

conexion=DriverManager.getConnection("jdbc:odbc:PRODS "); sentencia=conexion.createStatement(); }

catch(Exception e){System.out.println("Error"+e.toString());} }

public float getPrecio(String nombre) {

try{ rs= sentencia.executeQuery("SELECT PRECIO FROM PRODUCTOS "+ "WHERE NOMBRE='"+nombre+"'");

if (rs.next()) return rs.getFloat("PRECIO");

} catch (Exception e) {System.out.println("Error: "+e.toString());} return 0; }

6

Se pide : Rellenar la clase ConsPrecioIU con el código necesario para que al pulsar el botón CONSULTAR PRECIO aparezca como resultado el precio de los productos escogidos. Por ejemplo, el resultado sería el siguiente :

si los precios actuales fueran los que aparecen en la tabla ACCESS anterior y se hubiera pulsado el botón CONSULTAR PRECIO con los siguientes datos de entrada:

La solución debe basarse en una arquitectura lógica e n 3 niveles y ser extensible ante un futuro cambio e n la lógica del negocio, ya que se está pensando e n “aplicar porcentajes de

(4)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

Precios

inicializarBD(): void

getPrecio(nombre:String): float

getPrecioMan(): float

getPrecioPer(): float,

getPrecioNar(): float

ConsPrecioIU

p: PreciosLN

“interface” PreciosLN

usa

getPrecioMan(): float

getPrecioPer(): float,

getPrecioNar(): float

8

void button1_actionPerformed(ActionEvent e) {

// En p tenemos el objeto con la lógica del negocio

String kgManz = textField1.getText(); // idem. kgPer y KgNar

try{m=Float.parseFloat(kgManz);} catch (Exception ex) {m=0;}

try{p=Float.parseFloat(kgPer);} catch (Exception ex) {p=0;}

try{n=Float.parseFloat(kgNar);} catch (Exception ex) {n=0;}

float precio = m*p.getPrecioMan()+ p*p.getPrecioPer() +

n*p.getPrecioNar();

Aviso a = new Aviso(this,"Precio es: "+precio);}

LA LÓGICA DEL NEGOCIO SE USA DESDE EL

MÉTODO DE ATENCIÓN AL EVENTO

NO ES EXTENSIBLE. EL PRECIO DE LOS

PRODUCTOS NO DEPENDE DE LA CANTIDAD.

HABRÍA QUE CAMBIAR LA PRESENTACIÓN:

if (m>10) precioMan = pr.getPrecioMan()*0.9;

// idem. con resto de productos y descuentos

(5)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU 9

Segunda Solución

ConsPrecioIU

p: PreciosLN

“interface” PreciosLN

usa

calcularPrecio(c1,c2,c3: String ): float

Precios

inicializarBD(): void

getPrecio(nombre:String): float

calcularPrecio(kgMan,kgPer,kgNar: String ) : float

10

EN LA PRESENTACIÓN AÑADIMOS UN ATRIBUTO

CON LA LÓGICA DEL NEGOCIO Y MÉTODO PARA

ASIGNARLA:

public class ConsPrecioIU extends Frame {

PreciosLN p;

void setLogicaNegocio(PreciosLN p) {pr=n;}

… }

public interface PreciosLN {

public float calcularPrecio(String kgManz,

String kgPer,

String kgNar);

}

(6)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

void button1_actionPerformed(ActionEvent e) {

// En p tenemos el objeto con la lógica del negocio

float precio = p.calcularPrecio(textField1.getText(),

textField2.getText(),

textField3.getText());

Aviso a = new Aviso(this,"Precio es: "+precio);

}

LA LÓGICA DEL NEGOCIO SE USA DESDE EL

MÉTODO DE ATENCIÓN AL EVENTO

12

public class Precios implements PreciosLN {

public float calcularPrecio(String kgManz,

String kgPer,

String kgNar) {

float m,p,n;

try{m=Float.parseFloat(kgManz);} catch (Exception ex) {m=0;}

try{p=Float.parseFloat(kgPer);} catch (Exception ex) {p=0;}

try{n=Float.parseFloat(kgNar);} catch (Exception ex) {n=0;}

return m*getPrecio("MANZANAS (Kg.)")+

p*getPrecio("PERAS (Kg.)")+

n*getPrecio("NARANJAS (Kg.)");}

// y los métodos inicializarBD y getPrecio…

}

LA LÓGICA DEL NEGOCIO SE OBTIENE

IMPLEMENTANDO LA INTERFAZ. PARA ELLO

SE REALIZAN LLAMADAS AL NIVEL DE DATOS

(7)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

13

Es una solución correcta…

• La solución sigue una arquitectura lógica en

tres niveles (están separadas el nivel de

presentación del nivel lógica del negocio en

clases y el nivel de datos en la BD)

– Presentación: ConsPrecioIU y Aviso

– Lógica del negocio: interfaz PreciosLN y clase Precios

• Es extensible

– Cuando se quiera añadir la regla del negocio para aplicar

descuentos según la cantidad comprada habrá que

reprogramar la clase calcularPrecios de la lógica del

negocio y la BD (para almacenar descuentos, etc.). Pero

NO CAMBIARÁ la clase de presentación

14

La solución propuesta, sin embargo,

no es extensible si se desea cambiar el

número y el nombre de productos

(lo cual no se pedía en el

enunciado…)

(8)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

• Una solución extensible ante el

posible cambio “se pueden

consultar los precios de varios

productos” aparece a continuación.

• Para ver si una solución es

extensible hay que saber con

respecto a qué posible cambio es

extensible

16

ConsPrecioIU p: PreciosLN

“interface” PreciosLN

usa calcularPrecio(datos : Vector): float obtenerProductos (): Vector

Precios inicializarBD(): void

getPrecio(nombre:String): float calcularPrecio(PrecCant: Vector) : float obtenerProductos (): Vector

(9)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

17

void button1_actionPerformed(ActionEvent e) {

// En p tenemos el objeto con la lógica del negocio

Vector datos= new Vector();

datos.addElement(label1.getText());

datos.addElement(textField1.getText());

datos.addElement(label2.getText()); // …

float precio = p.calcularPrecio(datos);

Aviso a = new Aviso(this,"Precio es: "+precio);

}

ConsPrecioIU p: PreciosLN

“interface” PreciosLN

usa calcularPrecio(datos : Vector): float obtenerProductos (): Vector

Precios inicializarBD(): void

getPrecio(nombre:String): float calcularPrecio(PrecCant: Vector) : float obtenerProductos (): Vector

18

• El método obtenerProductos() se

necesitará para colocar dichos

productos en la interfaz de usuario…

• Implementad dicho código…

(10)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

El resto de transparencias no las

he utilizado…

20

Nivel de Presentación

Nivel Lógica del Negocio

Nivel de Datos

(11)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

21

Restricciones de los Applets

• An applet can’t touch the local disk.

– No reading: you wouldn’t want an applet to read and transmit private information over the Internet without your permission. – No writing: Writing is prevented, of course, since that would be an

open invitation to a virus.

– Java offers digital signing for applets. Many applet restrictions are relaxed when you choose to allow trusted applets (those signed by a trusted source) to have access to your machine.

• Applets can take longer to display, since you must download the whole thing every time, including a separate server hit for each different class. Your browser can cache the applet, but there are no guarantees. Because of this, you should always package your applets in a JAR (Java ARchive) file that

combines all the applet components (including other .class files as well as images and sounds) together into a single

compressed file that can be downloaded in a single server transaction. “Digital signing” is available for each individual entry in the JAR file.

• No puede hacer una conexión de red a otro nodo de Internet que no sea aquél de donde se ha descargado

22

Ventajas de los Applets

• There is no installation issue. An applet has true platform independence (including the ability to easily play audio files, etc.) so you don’t need to make any changes in your code for different platforms nor does anyone have to perform any “tweaking” on installation. In fact, installation is automatic every time the user loads the Web page that contains applets, so updates happen silently and automatically. In traditional client/server systems, building and installing a new version of the client software is often a nightmare.

• 2.You don’t have to worry about bad code causing damage to someone’s system, because of the security built into the core Java language and applet structure. This, along with the previous point, makes Java popular for so-called intranet client/server applications that live only within a company or restricted arena of operation where the user environment (Web browser and add-ins) can be specified and/or controlled.

(12)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

• Applets are built using an application framework. You inherit from class JApplet and override the appropriate methods. There are a few methods that control the creation and execution of an applet on a Web page

• init( ): Automatically called to perform first-time initialization of the applet, including component layout. You’ll always override this method. • start( ): Called every time the applet moves into sight on the Web

browser to allow the applet to start up its normal operations (especially those that are shut off by stop( )). Also called after init( ).

• stop( ): Called every time the applet moves out of sight on the Web browser to allow the applet to shut off expensive operations. Also called right before destroy( ).

• destroy( ): Called when the applet is being unloaded from the page to perform final release of resources when the applet is no longer used • Note that applets are not required to have a main( ). That’s all wired

into the application framework; you put any startup code in init( ).

24

Ejecución de applets

• To run this program you must place it inside a Web

page and view that page inside your Java-enabled

Web browser. To place an applet inside a Web page

you put a special tag inside the HTML source for that

Web page to tell the page how to load and run the

applet.

• Al principio (applets de AWT)

• <applet code=Applet1 width=100 height=50>

</applet>

• Después (Applet de Swing)

• With Internet Explorer, the extension mechanism is

the ActiveX control, and with Netscape it is the

plug-in. In your HTML code, you must provide tags to

support both.

(13)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

25

Ejecución de applets

<html><head><title>Applet1</title></head><hr>

<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93“ width="100" height="50" align="baseline" codebase="http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0">

<PARAM NAME="code" VALUE="Applet1.class"> <PARAM NAME="codebase" VALUE=".">

<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2"> <COMMENT>

<EMBED type="application/x-java-applet;version=1.2.2"

width="200" height="200" align="baseline“ code="Applet1.class" codebase="." pluginspage="http://java.sun.com/products/plugin/1.2/plugin-install.html">

<NOEMBED> </COMMENT>

No Java 2 support for APPLET!! </NOEMBED> </EMBED> </OBJECT> <hr></body></html> 26

Con appletviewer

• Sun’s JDK (freely downloadable from java.sun.com)

contains a tool called the Appletviewer that picks the

<applet> tags out of the HTML file and runs the

applets without displaying the surrounding HTML

text.

• Because the Appletviewer ignores everything but

APPLET tags, you can put those tags in the Java

source file as comments:

// <applet code=MyApplet width=200 height=100>

// </applet>

• This way, you can run “appletviewer MyApplet.java”

and you don’t need to create tiny HTML files to run

tests.

(14)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

presentación o lógica del negocio?

• Validar la entrada tiene que ver con la presentación, con la interacción con el usuario, que ha escrito mal los datos: debe hacerse en el nivel de presentación

• Sin embargo, a veces no está tan clara la diferencia entre nivel de presentación y lógica del negocio

– Si uno solicita sacar -500 € de un cajero no podrá hacerlo porque no tiene sentido según la “lógica del negocio” de los cajeros automáticos

– Si uno solicita sacar 998 € de un cajero, no podrá hacerlo porque la “lógica del negocio” dice que no se sacan monedas de cajeros

– Si uno solicita sacar a débito 1500 € de un cajero (y no tiene s aldo) no podrá hacerlo porque así lo indica la “lógica del negocio”

– ¿Los datos -500, 998 y 1500 son erróneos? Algunos podrán comprobarse en la presentación y otros en la lógica del negocio.

• En el ejemplo anterior del gestor de billetes…

– ¿La restricción de que los nombres deben tener al menos 5 caracteres y deben ser todos alfabéticos es una regla del negocio? ¿O es un problema de presentación?

– ¿Qué sucedería si después se decidiera no dar billetes si no se proporciona el nombre y el apellido? El código anterior NO VALDRÍA y tendríamos que cambiar el nivel de presentación. ¿Pero no es en realidad un cambio en una regla del negocio?

• Usando Applets (o JSPs ) no importaría ya que el nivel de presentación “se instala” en el lado del servidor y se ejecuta en los clientes. Cambiar la lógica del negocio o presentación NO requiere reinstalar los clientes

28

¿Validar la entrada es nivel de

presentación o lógica del negocio?

• Prever los cambios y colocarlo donde

mejor convenga

(15)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

29

The jsp:setProperty Action

• <jsp:setProperty att=val*/>

• Set bean properties, either explicitly or

by designating that value comes from a

request parameter.

• Legal attributes are

– name="beanName"

– property="propertyName|*"

– param="parameterName"

– value="val"

30

The jsp:getProperty Action

• <jsp:getProperty name="propertyName "

value="val"/>

(16)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

• <jsp:plugin attribute="value"*>...

</jsp:plugin>

• Generates OBJECT or EMBED tags, as

appropriate to the browser type, asking

that an applet be run using the Java

Plugin.

32

The jsp:forward Action

• <jsp:forward page="relative URL"/>

• Forwards request to another page.

(17)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

33

JSP Introduction

• JSP makes it easier to create and maintain HTML, while still

providing full access to servlet code

• JSP pages get translated into servlets

– It is the servlets that run at request time

– Client does not see anything JSP-related

• You still need to understand servlets

– Understanding how JSP really works

– Servlet code called from JSP

– Knowing when servlets are better than JSP

– Mixing servlets and JSP

• Other technologies use similar approach,

but aren't as portable and don't let you use

Java for the "real code"

34

Uses of JSP Constructs

• Scripting elements

calling servlet code

directly

• Scripting elements

calling servlet code

indirectly (by means

of utility classes)

• Beans

• Custom tags

• Servlet/JSP combo

(MVC), with beans

and possibly custom

tags

Simple

Application

Complex

Application

(18)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

JSP Scripting Elements

JSP Expressions

• – Format: <%= expression %>

• – Evaluated and inserted into the servlet’s output. • • JSP Scriptlets

• – Format: <% code %>

• – Inserted verbatim into the servlet’s _jspService method • • JSP Declarations

• – Format: <%! code %>

• – Inserted verbatim into the body of the servlet class • • Predefined variables

• – request, response, out, session, application • • Limit the Java code that is directly in page

• – Use helper classes, beans, custom tags, servlet/JSP combo

36

JSP include Directive

• <%@ include file="url" %>

• A file on the local system to be included

when the JSP page is translated into a

servlet

(19)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

37

Arquitectura física en 2 niveles:

cliente flaco/servidor gordo

• Parte de la lógica del negocio se

combina con el nivel de datos

NIVEL DE PRESENTACIÓN NIVEL DE LÓGICA DEL NEGOCIO 1 NIVEL DE DATOS + LÓGICA DEL NEGOCIO 2 CLIENTE SERVIDOR

• Se usan procedimientos almacenados (stored procedures)

en la BD. Un procedimiento almacenado puede servir para

ejecutar una serie de sentencias SQL.

• Comunicación Cliente/Servidor en SQL + Proc. almacenados

• Se necesitan APIs como por ejemplo JDBC y/o ODBC

• Deben instalarse DRIVERS de la BD en todos los clientes

NO LO

HE DADO

38

Arquitectura física en 2 niveles:

cliente flaco/servidor gordo

• El despliegue de la aplicación es alto: instalar drivers y configurar todos los clientes (Idem.)

• Cambiar de SGBD requiere reinstalar todos los clientes

– Aún peor: El lenguaje para definir procedimientos almacenados

suele ser propietario (propio de cada SGBD)

Cambiar el esquema de la BD puede afectar a los clientes (Idem.)

• Cambiar la lógica del negocio implica recompilar y desplegar en todos los clientes

– TAL VEZ NO, si afecta sólo a procedimientos almacenados

Costos de conexión con la BD son altos. Cada cliente una conexión. (Idem.) • La red se puede sobrecargar. Cada sentencia SQL usa la red.

– ESTE PROBLEMA SE SUAVIZA.

(20)

A. Goñi, J.R. Zubizarreta, J. Iturrioz. Dpto. LSI, UPV/EHU

Presentación

Datos

Referencias

Documento similar