jueves, 4 de enero de 2018

GoF patterns launcher and Chain of Resposibility pattern example (C++)

A C++ (codeblocks ide) project for GoF patterns practicing.It can be extended with the rest of patterns (command, state, factory, mediator, etc...).

Files in project:

main.cpp

:
#include 
#include 
#include "chainofresp.h"
#include "patternexec.h"

using namespace std;

const int CHAIN = 2;

int main()
{
    int sdirective = 2;
    PatternExec* _patterne = 0;
    string name ="CHAIN";
    string conf = "1000";

    switch(sdirective){
    case CHAIN:
        _patterne =  new PatternExec(new ChainOfResp(name,conf));
    break;
    default:
        return -100;

    }

   int r =   _patterne->execute();

   if(!r)
    cout << "Program ended correctly" << endl;

    return r;
}

patternexec.h

: It contains pattern's launcher (command) and specific pattern (in this case ChainOfResp) runner.
#ifndef PATTERNEXEC_H_INCLUDED
#define PATTERNEXEC_H_INCLUDED

#include 
#include 
#include 

using namespace std;

class Pattern {
public:
Pattern();
Pattern(string name, string conf);
virtual int run();
private:
    string _name;
    string _conf;
};
Pattern::Pattern() {}
Pattern::Pattern(string name, string conf) {
     _name = name; _conf= conf;
}
int Pattern::run() {
cout<< "Running an empty pattern " << endl;
return 10;
}
class PatternExec {

public:
PatternExec();
PatternExec(Pattern* pattern);
virtual int execute();
private:
    Pattern* _pattern;
};
PatternExec::PatternExec(Pattern* p){ _pattern = p;}
int PatternExec::execute() {
    return this->_pattern->run();
}


class ChainOfResp: public Pattern {
public:
ChainOfResp();
ChainOfResp(string name, string conf);
virtual int run();
void setConf(string conf);
private:
    string _staticName = "CHAIN";
    int _deep;
};
ChainOfResp::ChainOfResp(){}
ChainOfResp::ChainOfResp(string name, string conf){
   if( _staticName != name) cout<<"Incorrect pattern Name" <setConf(conf);
}
void ChainOfResp::setConf(string conf) {
 if(conf == "1000")
    _deep = 1000;
}
/**
Here is where pattern is applied
The value _deep indicates the TOPIC value which determines which component will process the call
*/
int ChainOfResp::run(){

Widget* aButton;
Widget* aField;
Dialog* aConfirm;
Application* anApp;

anApp = new Application(0, (TOPIC) _deep);
aConfirm = new Dialog(anApp, (TOPIC) _deep);
aField = new Widget(aConfirm, (TOPIC) _deep);
aButton = new Widget(aConfirm, (TOPIC) _deep);
cout << "Launch ChainOfResp from Button" << endl;
aButton->handle();
cout << "Launch CofResp from Field" << endl;
aField->handle();

cout << _staticName << " Pattern ended correctly " << endl;
return 0;
}

#endif // PATTERNEXEC_H_INCLUDED

chainofresp.h

: specific pattern implementation
#ifndef CHAINOFRESP_H_INCLUDED
#define CHAINOFRESP_H_INCLUDED

#include 
#include 

using namespace std;

typedef  int TOPIC;
const TOPIC NO_VALUE = -1;

class Handler {
public:
Handler();
Handler(Handler* sucessor,TOPIC topic);
 virtual int handle();

 virtual int doProcess();

private:
    Handler* _sucessor;
    TOPIC _topic;
    const static TOPIC _myTopic = 0;
};
Handler::Handler(){}
Handler::Handler(Handler* sucessor, TOPIC topic){
_sucessor=sucessor;
_topic = topic;
}

int Handler::handle() {
    cout<< "Handling from Handler class" << endl;

   if(_topic == _myTopic){
        _sucessor->handle();
   }else doProcess();

}
int Handler::doProcess() {
    cout<< "Processing!!! from Handler class " << endl;
}

class Widget: public Handler {
public:
Widget();
Widget(Handler* widget, TOPIC topic);
virtual int handle();
virtual int doProcess();
private:
    Handler* _parent;
    TOPIC _topic;
   const static TOPIC _myTopic = 1;
};
Widget::Widget(){}
Widget::Widget(Handler* w, TOPIC topic) {
    _parent = w;
    _topic = topic;
}
int Widget::handle(){
cout << "Hadling from Widget class " << endl;
 if(_topic == _myTopic){
    _parent->handle();
 }else doProcess();

}

int Widget::doProcess() {
cout << "Processing from Widget class " << endl;
Handler::doProcess();
}

class Dialog:public Handler{
public:
    Dialog();
    Dialog(Handler* h, TOPIC t);
    virtual int handle();
    virtual int doProcess();
private:
    Handler* _handler;
    TOPIC _topic;
    const static TOPIC _myTopic = 2;
};
Dialog::Dialog(){}
Dialog::Dialog(Handler* h, TOPIC t):Handler(h,t) {

}

class Application:public Handler {
public:
    Application();
    Application(Handler* h, TOPIC t);
    int handle();
    int doProcess();
private:
    const Application* _app = this;
    const static TOPIC _myTopic = 1000;

};
Application::Application(){}
Application::Application(Handler* h, TOPIC t):Handler(h,t){}


#endif // CHAINOFRESP_H_INCLUDED

Download project from Github

domingo, 3 de diciembre de 2017

Design by contract (Software engineering, Bertrand Meyer)

Software engineering (by Restless Aficionados)

1. Design by contract

As object-oriented techniques steadily gain ground in the world of software development. users and prospective users of these techniques are clamof object-oriented or more and more loudly for a “methodology” software construction - or at least for some methodological guidelines.

This article presents such guidelines, whose main goal is to help improve the reliability of software systems. Reliability is here defined as the combination of correctness and robustness or more prosaically, as the absence of bugs.

Everyone developing software systems. or just using them, knows how pressing this question of reliability is in the current state of software engineering. Yet the rapidly growing literature on object-oriented analysis, design, and programming includes remarkably few contributions on how to make object-oriented software more reliable. This is surprising and regrettable, since at least three reasons justify devoting particular attention to reliability in the context of object-oriented development:
The cornerstone of object-oriented technology is reuse. For reusable components, which may be used in thousands of different applications, the potential consequences of incorrect behavior are even more serious than for application specific developments.
Proponents of object-oriented methods make strong claims about their beneficial effect on software quality. Reliabitity is certainly a central component of any reasonable definition of quality as applied to software.
*The object-oriented approach, based on the theory of abstract data types, provides a particularly appropriate framework for discussing and enforcing reliability.
Reliability is even more important in object-oriented programming than elsewhere. This article shows how to reduce bugs by building software components on the basis of carefully designed contracts.

The pragmatic techniques presented in this article, while certainly not providing infallible ways to guarantee reliability, may help considerably toward this goal. They rely on the theory of design by contract. which underlies the design of the Eiffel analysis, design, and programming language’ and of the supporting libraries, from which a number of examples will be drawn.

The contributions of the work reported below include a coherent set of methodological principles helping to produce correct and robust software; a systematic approach to the delicate problem of how to deal with abnormal cases. leading to a simple and powerful exception-handling mechanism; and *a better understanding of inheritance and of the associated techniques (redeclaration, polymorphism, and dynamic binding) through the notion of subcontract, allowing a systematic approach to using these powerful but sometimes dangerous mechanisms.

Most of the concepts presented here have appeared elsewhere. They were previewed in the book “Object-Oriented Software Construction”; and a more complete exposition was presented in a recent book chapter,”from which this article has been adapted”. More profoundly, this work finds its root in earlier work on systematic program development and abstract data types. This article focuses on the central ideas, introducing them concisely for direct application by developers.

1.1. Defensive programming

1.2. The notion of contract

1.3. Assertions:Contracting for software

1.4. The role of assertions

1.5. Further sources

1.6. Observations on software contracts

1.7. Who should check?

1.8. Class invariants

1.9. On the assertion language

1.10. Documenting a software contract

1.11. Monitoring assertions

1.12. Why monitor?

1.13. Introducing inheritance

1.14. The concurrency issue

1.15. Invariants and dynamic binding

1.16. Dealing with abnormal situations

1.17.A disciplined exception-handling mechanism

1.18. Status of Eiffel

1.19. Acknowledgments

2. References

B. Meyer. “Design by Contract.” in Advances in Object-Oriented Software Engineering, D. Mandrioli and B. Meyer.eds.. Prentice Hall. Englewnod Cliffs, N.J.. 1991. pp. I-SO.

lunes, 5 de junio de 2017

Requisitos y patrones J2EE aplicables

Requisites and applied J2EE Patterns

1. Requisitos y Patrones de diseño en J2EE

Presentaremos una lista de requisitos que surgen a la hora de crear una aplicación J2EE. Junto al requisito, se indica el o los patrones que se suelen aplicar. Esto puede ser util a la hora de identificar cual puede ser (los) patrones a aplicar.

1.1. Capa de presentacion

Requisitos

Patrones

Preprocesamiento o postprocesamiento de la request

Intercepting Filter

Añadir la capacidad de logging, depuracion, u otro comportamiento que debe completar cada request

Front Controller

Intercepting Filter

Centralizar el control para el manejo de la request

Front Controller

Intercepting Filter

Application Controller

Crear un interfaz generico de tipo Command o un objeto que contenga el contexto, de manera que se reduzca el acoplamiento entre los elementos que manejan el control c y los elementos que actuan como helpers

Front Controller

Application Controller

Context Object

Si hemos de implementar nuestro Controller como un servlet o bien como JSP

Front Controller

Crear una vista a partir de varias sub-vistas

Composite View

Si hemos de implementar nuestra View como un servlet bien como JSP

View Helper

Como descomponer nuestra View y Model

View Helper

Donde encapsular los datos provenientes de la presentacion y su logica

View Helper

Si debemos de implementar nuestros Helpers como JavaBeans o como Custom tags

View Helper

Combinar multiples patrones de presentación

Intercepting Filter

Dispatcher View

Donde encapsular el manejo de la Vista y la lógica de Navegacion, lo que implica seleccionar una de las Vistas y servirla

Pattern Service to Worker

Dispatcher View

Donde guardar el estado de la Session

Session State on the Client

Session State in the Presentation Tier

Storing State on the Business Tier

Control de acceso del cliente a ciertas vistas

Design "Controlling Client Access"

Hide Resources From a Client

Controlar el flujo de requests hacia la aplicacion

Design "Duplicate Form Submissions"

Design "Introduce Synchronizer Token"

Controlar la llegada de submits duplicados

Design "Duplicate Form Submissions"

Introduce Synchronizer Token

Problemas de diseño al usar el mecanismo de populacion de valores estandar de JSP <jsp:setProperty>

"Helper Properties—Integrity and Consistency"

Reducción del acoplamiento entre la capa de presentación y la de negocio

"Hide Presentation Tier-Specific Details From the Business Tier"

"Introduce Business Delegate"

Particionar el codigo de acceso a datos

"Separate Data Access Code

1.2. Capa de negocio

Requisitos

Patrones

Reducir el acoplamiento entre la capa de presentación y la capa de negocio

Business Delegate

Poner en cache los servicios de la capa de negocio a los clientes

Business Delegate

Ocultar los detalles de implementacion de lookup/creacion/acceso de los servicios de la capa de negocio

Business Delegate

Service Locator

Encapsular las dependencias propietarias de lookup en los servicios

Service Locator

Proveer un metodo uniforme para lookup y creacion en los servicios de la capa de negocio

Service Locator

Ocultar la complejidad de las dependencias de los enterprise bean y el lookup de los componentes JMS

Service Locator

Transferir los datos entre los objetos de negocio y los clientes pasando por las distintas capas

Transfer Object

Proveer de un interfaz simple para los clientes remotos

Business Delegate

Session Façade

Application Service

Reducir las invocaciones a metodos remotos mediante el acceso a metodos que agrupen varias funcionalidades dentro de la capa de negocio

Session Façade

Manejar las relaciones entre los componentes enterprise bean y ocultar la complejidad de las interacciones

Session Façade

Proteger los componentes de la capa de negocio de ser expuestos directamente al cliente

Session Façade

Application Service

Proveer una capa uniforme de acceso a los componentes de la capa de negocio

Session Façade

Application Service

Implementar un modelo conceptual de dominio complejo mediante objetos

Business Object

Identificar objetos que manejan dependencias y sus objetos dependientes en el diseño de objetos de negocio y entity beans

Business Object

Composite Entity

Diseñar entity beans que manejan varias otras dependencias

Composite Entity

Reducir o eliminar la dependencia entre entity beans y el esquema de base de datos

Composite Entity

Reducir o eliminar la dependencia entre entity beans locales y entity beans remote

Composite Entity

Reducir el numero de entity beans y mejorar su manejo

Composite Entity

Obtener el modelo de datos de la aplicacion a partir de componer varios componentes de la capa de negocio

Transfer Object Assembler

Construcción dinamica del modelo de datos de aplicacion

Transfer Object Assembler

Ocultar la complejidad de la construcción del modelo de datos a los clientes

Transfer Object Assembler

Proveer de un procesamiento de peticiones y resultados en la capa de negocio

Value List Handler

Reducir la sobrecarga del uso de metodos lookup de enterprise bean

Value List Handler

Proveer de peticion-resultados cacheados para el cliente, dentro del servidor, con posibilidad de hacer-deshacer

Value List Handler

Elegir entre el uso de sessions beans con estado o sin el

Session Bean—Stateless Versus Stateful

Evitar el acceso directo por parte del cliente a entity beans

Wrap Entities With Session

Encapsular los servicios de la capa de negocio y ocultar los detalles de implementación

Introduce Business Delegate

Añadir logica de negocio dentro de un entity bean

Business Logic in Entity Beans

Move Business Logic to Session

Crear session beans como gruesos servicios de la capa de negocio

Merge Session Beans

Wrap Entities With Session

Reducir o eliminar sobrecargas de red o servidor debido a la comunicacion entity-bean-to-entity-bean

Reduce Inter-Entity Bean Communication

Particionar el codigo de acceso a datos

Separate Data Access Code

1.3. Capa de integracion

Requisitos

Patrones

Reducir el acoplamiento entre la capa de negocio y la de recursos

Data Access Object

Centralizar el acceso a la capa de recursos

Data Access Object

Minimizar la complejidad de los componentes de la capa de recursos y los de la capa de negocio

Data Access Object

Proveer procesamiento asincrono en aplicaciones empresariales

Service Activator

Enviar una peticion asincrona hacia los servicios de la capa de negocio

Service Activator

Procesamiento asincrono de una peticion, subdividiendola en sub tareas concurrentes

Service Activator

Persistir de manera transparente un objeto del modelo

Domain Store

Implementar un framework de persistencia propio

Domain Store

Exponer un servicio web mediante XML y un protocolo standard de Internet

Web Service Broker

Ofrecer de forma centralizada y distribuir servicios existentes bajo la forma de web services

Web Service Broker

2. Enlaces de interes

jueves, 13 de abril de 2017

POC of Suscription Board (Dojo,Dojo mobile, Spring MVC, JPA, Hibernate, Mysql)

You can find a Proof of concept of a "suscription board project", using: Dojo, Dojo mobile, Spring, JPA, Hibernate, Mysql and Amazon AWS technologies, at:

http://discussion.puertocerouno.net

Project now supports:

  • File attachments for discussion and replies

Regards.

jueves, 22 de septiembre de 2016

Entendiendo RESTful Web services

Entendiendo RESTful web services

1. RESTful Web services

1.1. Introduccion

Representational State Transfer (REST), es un concepto de web service que se parece en muchos aspectos a SOAP. La arquitectura REST esta formada por varios servidores y clientes. Los clientes realizan transiciones entre estados mediante acciones (peticiones a servidor para obtener o realizar un cambio de estado en los recursos), el servidor por su lado procesa las peticiones y devuelve los recursos. Un recurso puede ser cualquier concepto logico que es comprendido por ambos, cliente y y servidor, y que se transmite de forma acordada bajo una representacion. REST no depende o indica explicitamente un tipo de recurso o representacion. Dichos recursos pueden ser de cualquier tipo de dato que podamos establecer. Sus representaciones pueden ser por ejemplo, texto plano, HTML, XML, YAML, JSON, datos binarios, o cualquier otro tipo de formato que se entienda por el cliente y el servidor. Un sistema REST trabaja mediante URLs las cuales indican el tipo de recurso del que se trata, e instrucciones (veremos con el mapeo al protocolo HTTP, tales como GET, POST...), que indican la accion que se ha de realizar sobre el recurso, ademas del tipo de medio que representa el recurso (indicado por el MIME type), a tratar en las request y response. Es normal que nos recuerde a la forma de comunicacion de la WWW y el protocolo HTTP. Ademas de creador de parte del protocolo HTTP 1.0 y 1.1 Roy Fielding habla de “Representational State Transfer” en su tesis doctoral de 2000. World Wide Web es, por naturaleza, el gran sistema REST.

Uno de los principios fundamentales de los servicios RESTful es que se basa en un numero reducido de operaciones, que han de ser realizadas sobre un recurso. En este caso, el conjunto de operaciones se conoce como CreateReadUpdateDelete. Estos metodos se asignan a operaciones del protocolo HTTP facilmente sobre las acciones POST, GET, PUT y DELETE , respectivamente, mientras que SOAP utiliza el elemento envelope para indicar que tipo de accion realizar (el metodo que ha de ser invocado), REST basa las operaciones dentro del protocolo HTTP. En SOAP, el envelope, contiene ademas la referencia al recurso sobre el que se actua, mientras que REST dicha referencia va implicita en la URL.

En un servicio RESTful, la cabecera de peticion “Content-Type” indica al servidor acerca del la representacion del cuerpo de dicha peticion; la cabecera “Accept” o la extension de fichero en la URL, solicita el recurso de un tipo concreto, la cabecera de la respuesta “Content-Type”, informa al cliente la representacion del cuerpo de la respuesta.

Veamos algunas ventajas y desventajas que ofrece cada uno de los protocolos. La primera, un ws RESTful esta ligado a HTTP, miestras que SOAP es independiente del protocolo, lo que da ventaja a SOAP. Aunque no seria imposible crear un ws RESTful que fuese independiente, esto añadiria complejidad y dejaria de cumplir el concepto de REST. Ya que REST maneja: URLs, acciones y tipos de medio, al igual que lo hace HTTP lo que sirve como envelope para las request, response. Es posible con un mapeo directo a HTTP utilizar distintos tipos de dato, mientras que SOAP necesita que se pase a XML. SOAP es un protocolo redundante ya que se trata de un envelope contenido dentro de otro. Esta duplicidad del elemento envelope a la vez permite que sea independiente del protocolo HTTP y duplica la funcionalidad que ofrece directamente la referenciacion del recurso por URL y las acciones con metodos HTTP.

Una desventaja de los web services RESTful es que carecen de un tipado definido, como el que tiene SOAP a traves de los esquemas WSDL. Esto hace que no exista un contrato propio predefinido entre la peticion y la respuesta sino lo que se llama “contract-last”. Esto no impide que se pueda establecer dicho contrato, pero esta basado en una documentacion, haciendolo disponible mediante un API publica, en contraposicion a complejos esquemas XSD. Sin embargo algunos proveedores de ws RESTful llegan incluso a publicar dicha especificacion mediante un esquema XSD o en formato JSON.

plificar la funcionalidad aún siendo dependiente del protocolo HTTP, la aquitecutra RESTful se esta imponiendo a la hora de implementar Web Services y se integra ya en varios frameworks tales como Spring MVC.

1.2. Discoverability e Hypertext Application Language (HAL)

Una caracteristica importante de los ws RESTful es su “discoverability”. Mediante una combinacion de URL y metodos HTTP como OPTIONS, los clientes pueden descubrir los recursos disponibles que ofrece el web service, sin tener que establecer un contrato previo. De esta manera los clientes pueden saber las acciones que se pueden realizar sobre cada recurso. Aunque muchos proveedores de ws RESTful no ofrecen dicha posibilidad, es una ventaja central de la arquitectura REST. En WWW todo es posible de identificar mediante su URL, como usuario, es posible desde el navegador acceder a cualquier recurso publico y siguiendo la cadena de enlaces llegar al resto.

Esta restriccion se encuentra tambien dentro de las especificaciones REST. De manera que sea posible acceder a un recurso a partir de otro. Este concepto se conoce como “Hypermedia as the Engine of Application State” (HATEOAS), para ello se usa XML, YAML, JSON, o cualquier otro formato junto con hiperenlaces para informar al cliente acerca de la estructura del ws. Por ejemplo, una request-response hacia un web service podria ser de la siguiente manera.

/*peticion*/
GET /servicios/rest/ HTTP/1.1
Accept: application/json

200 OK

Content-Type: application/hal+json

{

"_directorio": {

"self": { "href": "http://site.net/servicios/rest" },

"cuenta": { "href": "http://site.net/servicios/rest/cuenta" },

"pedido": { "href": "http://site.net/servicios/rest/order" }

}

}

Asi el cliente conoce los recursos disponibles en el web service. Si desea acceder al servicio de “cuenta” mas adelante, puede realizarlo o bien mediante una peticion GET al un recurso especifico llamado una “collection request” o bien una peticion a una URI, que devuelve todos los recursos de ese tipo disponibles.

GET /services/Rest/account HTTP/1.1

Accept: application/json


200 OK

Content-Type: application/json

{

"value": [

{

"id": 1075,

"name": "Joe Doe",

...

}, {

"id": 1076,

"name": "Alice Green",

...

}

]

}

Esto presenta la desventaja de que la respuesta con la coleccion puede ser muy grande (enorme incluso). La solucion seria aplicar paginacion en la respuesta. Otro problema, es que se muestran los recursos propiamente, no su ubicacion (mediante una URL por ejemplo). Para esto una forma seria devolver una lista de enlaces, pero esto lo hace inviable a la hora de utilizar estos datos por la parte cliente. Por esta razon, muchos web services usan una combinacion de atributos y un enlace al recurso.

Otra accion que puede realizar el cliente es solicitar los recursos disponibles dentro del un recurso devuelto mediante la peticion OPTIONS a dicho recurso.

OPTIONS /servicios/rest/cuenta HTTP/1.1

Accept: application/json
/*respuesta*/

200 OK

Allow: OPTIONS,HEAD,GET,POST,PUT,PATCH,DELETE

{

"GET": {

"description": "Recursos disponibles dentro de cuentas",

"templateAcceso": "http://site.net/servicios/rest/cuenta/{id}",

"parametros": {

"$select": {

"type": "array/string",

"description": "Propiedades de cada recurso disponible.",

},

"$filter" ...

}

},

"POST" ...

}

La respuesta OPTIONS puede ser muy util ya que no solamente indica al cliente cuales son las acciones que puede realizar sobre el recurso, sino que puede ademas filtrarse de acuerdo con los “permisos” que dicho cliente tenga. Por ejemplo, si el cliente puede Read pero no Create, Update o Delete, la response devolveria la cabecera “Allow: OPTIONS,HEAD,GET “. Junto con las acciones que fuesen posibles para los distintos recursos y sus parametros como vemos en la siguiente peticion y sus respuestas:


OPTIONS /services/rest/cuenta/1075 HTTP/1.1

Accept: application/json

200 OK

Allow: OPTIONS,HEAD,GET,PUT,PATCH,DELETE

….

OPTIONS /services/rest/cuenta/1076 HTTP/1.1

Accept: application/json

200 OK

Allow: OPTIONS,HEAD,GET

 ...

El primer problema para descubrir los servicios web RESTful es que no existe un acuerdo previo establecido entre cliente y servidor acerca del formato de las reponses de tipo “discovery” (OPTIONS).

En los ejemplos hemos visto el uso de una representacion JSON de Hypertext Application Language (HAL), lo que es, uno de los standares emergentes pero no es el unico. En cuanto al contenido del cuerpo de la respuesta, no hay un protocolo, a menudo depende de la implementacion del API.

2. Enlaces de interes

Algunos enlaces:

viernes, 2 de septiembre de 2016

Introduccion a Groovy

Introduction to Groovy

1. En Java...en Groovy

Ejemplo basico en Java :

public class HelloEcho {
   public static void main( String[] args )
      System.out.println("Hello Echo!");
   }
}

Se ejecutaria tambien en Groovy !!

Veamos otras caracteristicas del lenguaje :

1) Es debilmente tipado, como JavaScript o Perl. 2) El ambito de metodos y atributos de clase es por defecto public. 3) Punto y coma al final de linea es opcional

asi, la sintaxis siguiente seria correcta:

class HelloEcho {
   static main( args ){
 def avar = « Echo ! »
 println "Hello ${ avar }"
   }
}

Ademas, como dijimos Groovy es un lenguaje dinamico, lo que no impide que sea un lenguaje interpretado. De heco, cada clase Groovy se compila como una clase Java (lo que lo distingue de otros lenguajes de la JVM), aun cuando escribimos y ejecutamos el codigo desde scripts (no clases formales), se compilara como clase Java.


//se compila en Java bytecode
println "Hello World!"
Otra forma, en Groovy, usando  clases :
class HelloEcho {
   def greet( snds ){
      "Hello ${snds}!"
   }
}

def earv = new HelloEcho()
println earv.greet("Echo !")

En el ejemplo vemos 3 caracteristicas del lenguaje:

1) El tipo de retorno del metodo "greet"" no es de un tipo concreto, asi que usamos el keyword def (semejante a var en JS). 2) Si no indicamos « return » el valor de retorno sera el devuelto por la ultima sentencia ejecutada. 3) La cadena « Echo ! » no es de tipo java.lang.String, esto es una de las caracteristicas mas interesantes, es de tipo « GString ». Este tipo de strings nos permiten evaluar variables en su interior asi como expresiones, similar a como hace el lenguaje Perl.

2. Instalando Groovy

Para la instalar Groovy y lanzar los ejemplos desde la consola :

1) Descargar la ultima version desde http://groovy.codehaus.org/Download

2) En Windows existe el instalador NSIS-Installer, para versiones en Ingles, Español, Aleman y Frances.

3) Instalacion manual : Descomprime el paquete en un directorio, con permisos suficientes, por ejemplo C:\groovy en Windows, /usr/local/groovy en Linux.

4) Crear la variable de entorno GROOVY_HOME que apunte hacia ese directorio.

5) Debes tener instalado Java (JRE 1.4 o superior), y declarada la variable JAVA_HOME.

6) Añadir al PATH : GROOVY_HOME/bin

Ya puedes ejecutar scripts *.groovy ! Puede hacerlo de 3 formas :

1) La mas sencilla es a partir de ejecutar el interprete (es un lenguaje script, recuerda!). Asi el ejemplo anterior se ejecutaria desde la linea de comandos :

// hello-echo.groovy tiene permisos de ejecucion
$>groovy hello-echo.groovy

2) Lanzar el propio shell de groovy : groovysh

3) Lanzar la consola basada en Java Swing de Groovy , esta es la opcion mas recomendada para principiantes (no olvides configurar en las opciones, los jar necesarios para el classpath).

3. Tipos de dato

Una vez instalado Groovy (ya veremos como añadirlo a IDEs como Eclipse, mediante sus Plug-in), empezaremos a explorar el lenguaje. Empezando por los tipo de dato que soporta. Al contrario de Java, en el que existen tipos basicos, en Groovy todo es objeto (Smalltalk). Ademas, a la hora de ejecutar una sentencia, por ejemplo un bucle, existen multiples formas de hacerlo. Por ejemplo :

//escribe hola 3 veces
3.times {
   println "hola"
}
(1..3).each {
   println "hola"
}

El codigo print »Hola » se encuentra dentro de lo que se define como Closure, es importante este concepto de bloques de codigo. En Groovy se aceptan todos los tipos de tato Java (para ello se llama a los wrappers -Integer, Double,Boolean…-, en lugar de los tipos basicos). Para las collections como maps y list, se tratan de forma parecida a PHP o Perl. Las listas son en realidad instancias de  java.util.ArrayList  y los maps de java.util.HashMap, por lo que disponemos de sus metodos, sin embargo Groovy añade la posibilidad de acceder a los indices con el operador '[]' y en el caso de maps con la notacion punto.


//List y Maps en Groovy
def lista = [9,1,2,8,3,0,4,5,7,8, 2,4, 0, 0, 1]
def map = ["clave":"valor"]

//
assert list.get(0) == 9
assert list[0] == 9
assert map.get("clave") == "valor"
assert map["clave"] == "valor"
assert map.clave == "valor"
assert map."clave" == "valor

def listVacia = []
def mapVacio = [:]

// En listas no necesario el operador .add() 
def lista = []
lista[9] = 10
assert lista[9] == 10
assert lista.size() == 10 
//iterar lista.each{ item →...}

El uso de rangos define una secuencia de valores que puede iterarse en ambos sentidos. Se usan a menudo para crear listas dentro de una lista, pero puede usarse en mas casos.


// operador rango [] en un string es semejente a substring() o charAt() on the string
println "Soyunstring"[0..7]
// salida : Soyunstr

//bucle indicado por un rango
(0..10).each { num -> print num }
// prints 012345678910
('a'..'d').each { letra -> print letra }
// prints abcd

En Groovy existen ademas otros metodos que se añaden a las colecciones. Estos vienen con el GDK. Para muchos de estos metodos, se usan las Closures del lenguaje.

4. Closures

Veamos algunos ejemplos de closures, podemos comprenderlo como bloques de codigo reutilizables.

//Scope
def nombre = "Abracadabra"
def conjuro = {
   println nombre
}
conjuro()
// escribe « Abracadabra »

Las closures son similares a « funciones anonimas » dentro de un script. Podemos pasar parametros, el tipo y el nombre, pero al tratarse de un lenguaje dinamico, el tipo se puede obviar:

def escribe = { elem -> print elem }
(0..9).each escribe
('a'..'f').each escribe
//0123456789abcdef

Existen parametros por defecto para las Closures, incluso si no lo declaramos, disponemos de, « it »

def escribe = { print it }
(0..9).each escribe
('a'..'f').each escribe
//  0123456789abcdef

// Otras formas de iterar
//1
[0,1,2,3,4,5,6,7,8,9].each escribe
//2
(0..9).each escribe
//3
10.times escribe
//4
0.upto 9, escribe
//5 
def lista =[0,1,2,3,4,5,6,7,8,9] 
for( num in lista) escribe.call(num)

En el caso del bucle « for », hay que usar una llamada a « call » dentro de « escribe ». Esto se debe a que for no puede acceder al cuerpo de la closure de « escribe », sino que debe ser un bloque semejante a Java. (ver la declaracion de « escribe »)

5. Enlaces de interes

Algunos enlaces: