Portada - Archivos - Sobre mí - Feed

Closure Design Patterns

25.04.2012

Design Patterns

These days I’m learning design patterns. There are a lots of documentation about software design patterns, but I’m interesting in closure design patterns.*

Many patterns imply object-orientation, so may not be as applicable in dynamic languages. Peter Norvig demonstrates that 16 out of 23 patterns in the Design Patterns book are simplified or eliminated, Design Patterns in Dynamic Languages.

I’ve found an interesting presentation of Venkat Subramaniam about Design Patterns in Java and Groovy and another presentation of Neal Ford about Design Patterns in Dynamic Languages. Here, I extract some patterns of these presentations that involve closures and add others patterns based on my own experience.

* Groovy makes no such distinction between closures or anonymous functions. I’m really trying to get at is how we can use tools such as first-class functions, lambdas and closures when implementing design patterns.

Closure Design Patterns

Execute Around Method

A pair of operation that needs to be performed before and after operations.

def operations(closure) {
    println "Open"
    closure()
    println "Close"
}

operations { println "Operation" }

===> Open
===> Operation
===> Close

Pluggable Behavior

Specify the behavior of an object at runtime.

def selectValues(number, closure) {
    def list = []
    1.upto(number) {
        if (closure(it)) list << it
    }
    return list
}

assert [2, 4, 6, 8, 10] == selectValues(10) { it % 2 == 0 }  // even
assert [1, 3, 5, 7, 9]  == selectValues(10) { it % 2 != 0 }  // odd

Iterator Pattern

Allows sequential access to the elements.

def listNumbers(closure) {
    (0..3).each { closure it }
}

listNumbers {
    if (it < 2) println "$it is a little number"
    else println "$it is a big number"
}

===> 0 is a little number
===> 1 is a little number
===> 2 is a big number
===> 3 is a big number

Dynamical Conditional Execution

Create and execute a conditional operation.

def greet(user, successClosure, failClosure) {
    if (isAdmin(user)) successClosure()
    else failClosure()
}

greet(user, { println "Hi Admin!" }, { println "Hello User" })

Template Method Pattern

Define common algorithm steps (getting a customer) and customizations (passed as a closure).

def withCustomer (id, closure) {
    def customer = getCustomer(id)
    closure(customer)
}

withCustomer(1234) { customer ->
    println "Found customer $customer.name"
}

Loan Pattern

Ensures that a resource is deterministically disposed of once it goes out of scope.

def withListOfWordsForEachLine(file, closure) {
    def reader = file.newReader()
    try {
        reader.splitEachLine(' ', closure)
    } finally {
        reader?.close()
    }
}

withListOfWordsForEachLine(file) { wordList ->
    println wordList
}

Command Design Pattern

Encapsulate all the information needed to call a method at a later time.

def count = 0
def commands = []

1.upto(10) {
    commands.add { count++ }
}

println "count is initially ${count}"
commands.each { cmd ->
    cmd()
}
println "did all commands, count is ${count}"

===> count is initially 0
===> did all commands, count is 10

Strategy Pattern

Define a family of interchangeable algorithms.

calcMult = { n, m -> n * m }
calcAdds = { n, m ->
    def result = 0
    n.times { result += m }
    return result
}

def calcStrategies = [calcMult, calcAdds]
calcStrategies.each { calc ->
    assert 10 == calc(5, 2)
}

Factory Pattern

Abstract the object creation process (currying as a function factory).

def adder = { x, y -> x + y }
def incrementer = adder.curry(1)

assert 5 == incrementer(4)

Method Combination

Build a method from components.

def sum = { Collection collection -> collection.sum() }
def first2 = { Collection collection -> collection.take(2) }
def take2andAdd = first2 >> sum

assert 3 == take2andAdd([1, 2, 3, 4, 5])

Polyglot Programming

27.03.2012

Polyglot Programming

How many programming languages do you know?

Most programmers know several languages. I, as web developer, work on a daily basis with Groovy, SQL, Bash Scripting, HTML, CSS, JavaScript…

Learning different languages allows us to solve problems with the most appropriate language and to explore new paths of thinking about computational problems.

Neal Ford coined the term polyglot programming, to refer about this topic.

I think it’s important in this day and age of polyglot programming to understand a variety of different languages, as they are the design tools we use to craft software. Just like regular engineers must understand the physical properties of different materials, we should understand the capabilities, strengths, and weaknesses of different languages. And when to apply them.

Neal Ford

Polyglot JVM

Java has long been known simply as a programming language. Today, when thinking in Java we refer also a robust and mature development platform. Currently, the Java Virtual Machine (JVM) supports over 200 different programming languages.

These days I have been exploring different languages on the JVM: Java, Groovy, Scala, Clojure… I shared my experiences with others developers at Codemotion 2012.

Hope you enjoy the slides.

Create your own Groovy type conversion

06.02.2012

Type conversion the standard way

Type conversion or casting is a programming language method for changing an object’s data type into another.

I’m sure you are familiar with this code that converts a String to an Integer.

def number = (Integer)'1'
def number = '1'.toInteger()
def number = '1' as Integer

If I want to convert the type of my own objects, I need to create a method to achieve this goal. I copy object properties to another object in a generic way; if a property exists on target object, I copy it from the source object.

class User {
    String name
    String city
    Integer age

    def toAdminUser() {
        def adminUser = new AdminUser()
        copyProperties(this, adminUser)
        return adminUser
    }

    def copyProperties(source, target) {
        source.properties.each { key, value ->
            if (target.hasProperty(key) && !(key in ['class', 'metaClass'])) {
                target[key] = value
            }
        }
    }
}

class AdminUser {
    String name
    String city
    Integer age
}

Now I can do something like this:

adminUser = user.toAdminUser()

Type conversion the fancy way

Great, but I want to use this fancy way to coerce one type to another:

adminUser = user as AdminUser

Simple, Groovy supports operator overloading and creating your own type conversion is really easy: we can override the asType() method.

class User {
    String name
    String city
    Integer age

    Object asType(Class clazz) {
        if (clazz == AdminUser) {
            def adminUser = new AdminUser()
            copyProperties(this, adminUser)
            return adminUser
        }
        else {
            super.asType(clazz)
        }
    }

    def copyProperties(source, target) {
        source.properties.each { key, value ->
            if (target.hasProperty(key) && !(key in ['class', 'metaClass'])) {
                target[key] = value
            }
        }
    }
}

GNU Screen

10.01.2012

GNU Screen is a full-screen window manager that multiplexes a physical terminal between several processes, typically interactive shells. With this tool, you can keep a process running after disconnecting an SSH session. Kudos to Diego Toharia and his blog post Screen en máquinas remotas.

Basic usage

Create a new screen session:

$ screen -S sessionname

Resumes a detached screen session:

$ screen -r sessionname

List all of the screen sessions:

$ screen -ls

Kill a session:

$ screen -S sessionname -X quit

Close all screen sessions:

$ killall screen

Useful key bindings:

Ctrl + a, d Detach screen from this terminal
Ctrl + a, c Create a new window
Ctrl + a, space Switch to the next window
Ctrl + a, backspace Switch to the previous window
Ctrl + a, A Rename current window
Ctrl + a, " List of all windows for selection
Ctrl + a, k Destroy current window
Ctrl + a, ? Show key bindings

Multiple shells open in the same terminal:

Ctrl + a, | Split vertically
Ctrl + a, S Split horizontally
Ctrl + a, tab Switch the input focus to the next region
Ctrl + a, X Kill the current region
Ctrl + a, Q Delete all regions but the current one

A worry-free session

$ ssh me@server.com
$ screen -S sessionname
$ start something really important

Disconnect from the server (panic at other times without screen).

$ ssh me@server.com
$ screen -r sessionname

Everything is fine, keep working.

Automate your job

After disconnection, you can log into the remote machine and reattach the session in a single step:

$ ssh me@server.com -t "screen -r sessionname"

How can we improve this? autossh is the answer.

autossh, automatically restarts an SSH session and reattaches a session transparently:

$ ssh me@server.com
$ screen -S sessionname
$ Ctrl + a, d
$ exit
$ autossh me@server.com -t "screen -r sessionname"

In fact, autossh include a script called rscreen for perpetual sessions.

OK, it works. But it’s not so great because first you need to connect to the server, create a new screen session, detach the screen, exit from the server and finally connect it again with autossh.

What can we do? You can use screen -R to reattach a session or even create it first. Finally we solve all problems:

$ autossh me@server.com -t "screen -R sessionname"

Magic in Software Development

19.12.2011

My opinion about magic in software development coincides with these great posts:

Do You Believe In Magic?

Magic in software development

I extract some fragments of them that I would like to highlight.

Bad word: Magic

I often find that people talk about magic when referring to programming languages and frameworks.

The concept that some particular language features are more magical than others is insane. None of it involves fairy dust or anything particularly complicated; it’s all just programming.

There is absolutely no logic in calling language features magical. It implies that certain programming techniques are inherently fantastic and strange. That’s only the case if you don’t understand the language.

The correct response is not calling arbitrary features magic. The correct response is to keep learning how to write code and overcome your ignorance.

Magic rocks!!

Ultimately, you can continue using magic, but what’s magic? I’d define it as anything below your current level of abstraction that you don’t understand.

Any sufficiently advanced technology is indistinguishable from magic.

Arthur C. Clarke

Magic is a good idea, we don’t understand exactly how quantum physics works but we accept that it does and make good use of it.

Now, if you don’t understand some feature of your favorite framework or how it works behind the scenes, don’t worry. Do not be intimidated, just learn and enjoy without worrying about every detail.

Functional Programming with Groovy

28.11.2011

The diversity of languages and programming paradigms allows us to solve existing problems by thinking of solutions from very different approaches.

But why should a Groovy developer learn functional programming?

As I learned about functional programming, I found good ideas but I also found that it brought new clarity to my thinking about the design of class and methods. It also allowed me to write more concise code and to make it easier to reuse.

A few weeks ago, I spoke about functional programming with Groovy at Greach 2011. I presented basic concepts of the functional programming paradigm and then focused on how to apply them to improve the code that we write with Groovy.

Greach 2011

08.11.2011

Les voy a contar una historia.

Empecé a programar con Groovy el 4 de noviembre de 2010. Recuerdo la fecha perfectamente porque el día anterior firmé mi contrato con OSOCO.

Desde ese día he continuado programando con Groovy a diario. En OSOCO utilizamos Groovy en casi todos los proyectos que realizamos, así que teníamos una cita obligada en nuestro calendario: Spring I/O 2011.

Conocí a Alberto Vilches durante el Spring I/O 2011 y a lo largo del año hemos coincidido en distintos eventos, entablando amistad rápidamente.

Durante todo este tiempo he acudido a las reuniones de Madrid Ágil, y creo que de alguna forma este hecho contribuyó a que Rafael Luque pusiera en marcha una idea que tenía desde hace tiempo, crear el grupo de usuarios de Groovy de Madrid.

El día 31 de marzo de 2011 se celebró la reunión inicial del grupo Madrid GUG.

En esa primera reunión Marcin Gryszko realizó una presentación sobre Testing legacy applications with Spock. También fue el primer día que Alberto nos contó su intención de organizar un evento que tratara en exclusiva sobre Groovy y todo el ecosistema que existe alrededor de este lenguaje: Grails, Griffon, Gradle, GPars, Spock, Gant, Gaelyk…

En aquel momento todo estaba por definir: la fecha, el lugar, los ponentes, los patrocinadores, incluso el nombre del evento. Hoy sabemos que esa idea era Greach. Tampoco me podía imaginar que unas semanas más tarde Marcin formaría parte del equipo de OSOCO.

El 4 de noviembre de 2011 se celebró Greach, justo un año después de que yo comenzara a programar con Groovy. OSOCO fue uno de los patrocinadores del evento. Marcin presentó un fantástico taller de Groovy Metakoans y yo presenté una sesión sobre Programación Funcional con Groovy.

Greach ha sido uno de los mejores eventos sobre desarrollo en los que he estado. Fue una gran conferencia con magníficas sesiones, vinieron los líderes de los proyectos Groovy, Grails y Griffon y la organización intentó cuidar cada detalle para que todo saliera a la perfección.

Al finalizar la conferencia, cuando prácticamente todo el mundo se había marchado, yo caminaba junto a Alberto hacia la salida. Le felicité por la organización del evento, le di un abrazo y por supuesto le di las gracias por haber hecho todo posible. Alberto me prometió que el año que viene Greach tendría más asistentes, más sesiones, dos días de duración y sería mucho mejor.

Esta es mi forma de unir los puntos.

Conferencia Agile Spain 2011

27.10.2011

Los días 20 y 21 de octubre de 2011 se celebró la Conferencia Agile Spain 2011.

He necesitado reflexionar durante algunos días para poder valorar la conferencia tal y como se merece. Después de resumir la experiencia a mis compañeros de OSOCO, me he dado cuenta de que realmente he aprendido y me he llevado muchas más cosas de las que en un principio imaginaba.

La conferencia del año pasado fue mi primer contacto con las metodologías ágiles y este año he tenido el privilegio de presentar una sesión junto con Marcin Gryszko, en la que hemos explicado cómo es la evolución de un proyecto gestionado con metodologías ágiles: BKOOL.

BKOOL at CAS 2011

Mi experiencia personal

De entre todas las sesiones a las que asistí, me gustaría destacar las siguientes:

Lo que superó todas mis expectativas:

  • He conocido a muchísima gente con grandes ideas y proyectos, personas con mucha ilusión y ganas de continuar mejorando.

  • He aprendido la forma en la que trabajan otros equipos, sus problemas, sus retos, sus soluciones.

  • Me han sorprendido los diferentes modelos de negocio de algunos proyectos, reflexionando desde un punto de vista económico.

  • He comprendido que ser ponente es algo realmente difícil, pero al mismo tiempo muy positivo y enriquecedor.

  • He recordado que una persona es capaz de llegar tan lejos como se proponga (aunque quizás nunca he llegado a olvidarlo).

My Manifesto

26.07.2011

Hoy he estado pensando cuáles son las máximas que mueven mi vida.

1. Ser feliz

2. Echarle morro

3. Reclamar lo que es justo

4. Currárselo mucho

5. Hacer que todo merezca la pena

No necesariamente en este orden, sino todas a la vez.

Clean Code

11.07.2011

Clean Code: A Handbook of Agile Software Craftsmanship es un libro que todo desarrollador debería leer al menos una vez en su vida.

Cuando se estudia programación, el centro del aprendizaje suele ser el propio lenguaje o la parte algorítmica, sin embargo otro de los aspectos más importantes de la programación es que el código sea simple, expresivo, fácil de mantener y que por supuesto, haga exactamente lo que queremos.

Contenido

El libro utiliza una gran cantidad de ejemplos y muestra muchísimo código. Algunos capítulos que me gustaría destacar son los siguientes:

  • Meaningful Names

    El primer paso para escribir buen código es que los nombres tengan significado. Las variables, métodos y clases deben tener un buen nombre para saber por qué existen y qué hacen.

  • Functions

    Las funciones tienen que ser pequeñas, deben hacer una única cosa y la deben hacer bien, manteniendo un sólo nivel de abstracción. También hay que intentar reducir el número de argumentos al mínimo.

  • Comments

    No comentes mal código, reescríbelo.

  • Formatting

    El formateo del código tiene un único propósito: la legibilidad. Aquí se describe The newspapper methapor, al leer código las primeras funciones que encontremos tienen que ser las principales y si lo deseamos podemos entrar en detalle más abajo.

  • Objects And Data Structures

    Los objetos ocultan sus datos y exponen funciones para operar con ellos, mientras que las estructuras de datos los exponen directamente.

  • Error Handling

    Hay que intentar separar la lógica de nuestra aplicación del control de excepciones, así como no devolver ni pasar valores nulos en las funciones.

  • Unit Test

    Una parte muy importante al construir aplicaciones son las pruebas y los test. Lo ideal es hacer TDD y crear un código en los test que sea igual de bueno que el del resto de la aplicación.

  • Classes

    Las clases también tienen que ser pequeñas para intentar tener una alta cohesión.

  • Emergence

    Para crear un buen diseño emergente hay que ejecutar todos los test, eliminar la duplicación de código, expresar la intención al programar y minimizar el número de clases y de métodos.

Presentación

Al finalizar el libro decidí realizar una presentación para compartir lo aprendido con mis compañeros de trabajo y también hice la presentación en el grupo de Madrid Ágil. Que la disfruten…

Si quieres leer más, consulta los Archivos >>