BLDD, a DD to Dominate Them All

| Comments

BullshitLess Driven Development

Spanish version

This is a letter for you, small grasshopper programmer, that yesterday you discovered that an if is an instruction so awesome that it allows that you could run a small piece of code with a predetermined condition, and that tomorrow you will discover, very probably, what a recursive function is, what an object is and that Singleton is a design pattern, or at least this they say over there…

This is a letter for you, so that you remember it in the hard moments of your life as a programmer and so that you look for a starting point in this wonderful professional current, full of green phosphorite letters with meaning of victory, of unpaid and ungrateful overtime and of undecipherable bugs, more hidden than the dignity of the voters of Donald Trump.

Smile at life, you lucky man. Praised is your future!

And the fact is that today, here, I want to tell you some situations that, surely, sooner or later, and more sooner than later, you will live in some of your future exploits. In these situations there are monsters, mortal pitfalls and up to lethal weapons. There are unconnected religions, double morals and the worst thing of all, bullshits as to feed half the entire Congo and to remain for a Christmas dinner where the whole Sierra Leone is invited. Free Moët for all included.

Let’s start with some sentences of the guild…

This is bad.

Yes, my friend.

Although you do not believe it, quite all that you’ll do in your life will be a real shit for some. It does not matter that your experience is just one day programming, or that you have it often inevitable pressure of those who pay your salary, or simply you cannot do it better. Never mind. Do what you do, it will smell in a disgusting way you can not still imagine.

And possibly it will be. Possibly your creation will be poor and with many mistakes, but we are lucky of that surrounded as we are surrounded with constructive and charitable souls, where very few times one “Is bad” will come accompanied from one “If you want I can sit next to you and we can make it much better”.

Do not dazzle you, you are not alone.

We are the society of “You don’t know” and not the one of “I Believe that it can be improved”, and we are so complex with our shits, that we need to put at the beginning of our phrases one “IMHO” because, otherwise, the fact that we think that every single line of code done by other hands far from ours is garbage ipso facto, can be too evident.

The most polite have decided to mask all this reality with a great and lovely word, and dear reader… save it properly in your untrained memory.

Legacy Code.

These of product…

Other one of the sentences that is so common among our cloud of egos is “these of product, how heavy they are with their useless pixels” or seemed, normally with burlesque and challenging tone.

Yes, my friend, a classic topic between partners of department, very habitual in any company where some people take care, not only about how amazing is the technical part, but how good are sales. Not all the companies are so modern and liberal as to ignore sales metrics and final user inputs.

Ah… these of product that want to fuck our lives with stupid things like pixels for our landing pages, with seemingly useless changes in the web, or with integrations with payment methods or shipping providers. As soon as you meet these miserable, please, spit in their faces, because of their disrespectful behaviour toward us, the programmers, whom we do the projects in the company we’re working in with new technologies, even unknown technologies, just because they are cool and freaking trending, that we decide that the new project in the company will be designed with 378 different layers, each more useless, just because some nobody with hat and whose fans have tattooed the Clean Code book in its soft buttocks, said someday that it was the last thing in being hipster, even without knowing the real goal of our project and its timings. To us, that we do a form in 5 days because we want it to be compatible with the GameBoy Advance, with the small screen of the microwave and with the thermostat of our heater. To us, that nobody prevents us from being the whole day with the nose hooked on that on-line groups, more likely an ego orgy than a place where to learn something.

To us that we are so responsible.

I will tell you a secret. An undertone. Don’t let anyone hear us.

If anyone knew each of the shits that we do in this paid work, or if they knew each of the erroneous architectural decisions that we take for the mere fact of wanting to be the cooler, we all would be dismissed. All of us.

Although I suppose that we prefer to say “These of product…”, to show off that we not only can do a foreach, but also we can do the work of half a company, and continue with our lives with the head quite high, leaving a disgusting track of Legacy Code in our backs.

In my company we do…

This is a brilliant pearl, the sapphire of the phrases, although to find it you will have to strain a little bit and leave your house in order to let the light of the sun impact your smooth complexion, and start relating to other persons of other companies.

Be courage!.

And the fact is that you will discover that all the other companies use the last of the last. Good shit in their stack of technologies and hard drugs in its last incorporation (when they do not have authentic machines in its backend department, they have an ex-facebook in its system department or a super crack as CTO come from the far elvers mountains).

All the companies are equipped technologically extremely well, with a workforce build with the best of the best. You will understand this in the future, when you start working in a new company. You’ll never, ever, have the printout of having begun being employed at a slaughter full of corpses, rotting during the last 10 years.

Remember… never!

And the fact is that, my friend, it seems that having that all our code is a shit, and that those of product are the whole day between a “put this pixel here” and a “put this banner there”, it turns out that we do not have time to make our work properly. But remember! it is not because we are all authentic bunglers in most cases, not at all. It is because we’ve had not time.

But Uncle Bob says that…

Rapid and precise.

  • Is Uncle Bob here?
  • Does Uncle Bob know the project?
  • No, am I right?
  • Then I don’t give a shit what Uncle Bob says.

End of the discussion.

The key of everything, BLDD

Said this, you will see that the world is an inhospitable place, full of people with few desires of helping you and too much fucking you all and seeing you sinking. But nevertheless you have to do a switch because, given the circumstances, you can’t do it better, or you have to do a project in a couple of days and unfortunately you cannot make it compatible with the handlebar of your bike.

I present to you, humbly, the BLDD, abbreviation of BullshitLess-Driven Development (another thing that you need to learn is that, here, we write everything with abbreviations, in English although both speakers are from Albacete and that you must put between phrase and phrase the word Trade-off. If you do not do this, you will not be accepted by the exclusive circles).

The BLDD is a very simple practice, based on ignoring all those frequencies that are broadcasting bullshit. Exactly the same as what is commonly known as sending to fuck off, but with a modern name and in a way that can make us feel cooler and much more modern.

It is commonly recommended to make tests first and then implement BLDD. Otherwise, you’re shit.

This methodology counters almost all other strategies ending with DD, and is applicable almost in all cases.

  • If someone tells you that your project should have tests first… BLDD
  • If someone tells you that you’re too coupled to the framework, even if you’re only trying to do you CV? BLDD
  • If someone tells you that your code is shit and that can be redone properly in DDD? in that case, break his neck BLDD

As you can see, it works like Swiss knife. The good part of this practice is that be sure that anyone, any time, will tell you how you should use it and implement it. An endless amount of formulas, each one more incredible, can be part of your executions when implementing BLDD.

Some ending advices

To end this cookbook of the good developer, a small list of ideas and advices for your body…

  • IMHO, if any time you make a public presentation in a conference, take with you on stage the red DDD book. As soon as you see anyone in the first row sleeping or playing with his mobile, please, throw him the book with as much emphasis as you can. It will hurt so much. If he continues sleeping, you still have other colours…
  • IMHO, a conversation ends when someone tells the word Annotation
  • IMHO, to make friends on Twitter you only have to say “TDD is dead”. To make enemies, exactly the same.
  • IMHO, your project tests is like the unemployment. The important is the coverage you can tell other people, not the real quality of the cases.
  • IMHO, in Barcelona, the developers are used to changing from one company to another one once per year. At 40 years, your wage will be around 120.000 and you will be a fucking god in 20 languages, including assembler. You will still be extremely stupid and lazy when defining variable names and all your code comments will be in your native language
  • IMHO, nowadays, Event Sourcing is super mainstream. Yeah, exactly, this super useful practice in all our sector. So I calculate that in about 5 years, in some companies you will work in, you will find a set of intractable, incomprehensible and undocumented classes and packages, fruit of this fashion. You’re welcome.

Conclusions

I will finally tell you that good luck. Try to learn as much as you can, read as much as you can and teach as much as you can, but never let anyone tell you how to do your stuff (unless someone tells you to not use Prestashop. In that case, please, follow the advice blindly). Have enough criterion to accept that many of the technologies, architectures and practices you will discover and listen in conferences, in your friends talks or in Twitter threads, are not useful at all in your projects.

Work hard, follow your dreams and remember that you have to buy a lot of technical books, and as soon as you receive them, you need to take a picture and publish on Twitter something like… “My new plan for the weekend”.

For everything else, BLDD.

El Peligro De Hablar Español en Catalunya

| Comments

Odiado español.

Es muy posible que tras el sensacionalista Tweet de Rosa Díez, una mujer profundamente admirada y seguida por todo el pueblo español, te hayas quedado con ganas de más. Recordemos que la señora Díez reaccionaba de una forma muy natural en las redes sociales tras leer un artículo de un medio de comunicación titulado “El peligro de hablar en español en Estados Unidos”.

Para los que aún desconocéis dichos hechos, decir que ella pedía a gritos un artículo semejante en relación con la persecución que sufre la gente en Catalunya por hablar en español. Sí, has leído bien. Catalunya, Español, Persecución.

Pues bien, les comentaré durante unas cuantas líneas de qué trata esta persecución, cuales son algunos de los casos más delirantes ocurridos en estas tierras colonizadas por los catalano-parlantes y les daré algunos consejos para aquellos que decidan que Catalunya pueda ser un objetivo para su próximo safari en vacaciones.

Agárrense bien al sillón, valientes curiosos, porque todo lo que lea a continuación puede ser motivo de pérdida de conocimiento para pequeños y mayores, y objeto de traumas perpetuos para los más sensibles.

Empiezo.

Antiguamente

Una vez conocí una persona llamada Juan. Juan era de familia emigrante durante la época de la transición, y tras partir con sus padres de un pueblecillo pequeño en el norte de Extremadura, llegaron a tierras inhóspitas en el extra radio de Barcelona.

Por aquel entonces, la llamada ciudad de Badalona era el centro cultural de Catalunya. Todo el mundo hablaba catalán antiguo, forjado en las oscuras cuevas de los pueblos unidos del norte, y cualquier humano andante con habladurías que no fueran en el idioma ario era objeto de persecución, dilapidación y extorsión por parte de los integrantes de aquella cultura pseudoradical.

Todo cuanto Juan y su familia conoció en tierras lejanas fue miedo y soledad, y aunque sus pensamientos permanecían permanentemente en su amado pueblo, ya dejado atrás, su futuro les llamaba susurrante y provocador.

“Veniu, estimats conciutadans. Integreu-vos i parleu en català”

Venid, amados conciudadanos. Integraos y hablad en catalán, les decía el destino, amparado con el fino velo del desprecio hacia aquellos pobres humanos diferentes y extraños. Ellos, asustados por aquella voz incomprensible de palabras hechizadas, decidieron taparse los oídos por el miedo a volverse locos y dementes. ¿Hasta cuándo podrían soportar esta situación? ¿Qué les deparaba la vida?

Juan y su familia se desvanecieron en su oscura morada de Badalona, y sus cuerpos yacieron escondidos e inevitablemente ignorados, como todo aquel inconsciente que se atrevió a cruzar poniente sin hablar la lengua envenenada del mismísimo señor de las tinieblas.

Lo recuerdo con cariño, y es que fueron buenos tiempos.

Actualmente

Esta bien podría ser una noticia de “el país”, y a usted, querido lector, no le extrañaría demasiado descubrir una vez más que, en Catalunya, los seres vivientes somos malvados con aquellos con los que diferimos en raza, lengua e identidad.

Yo soy ciudadano de Badalona.

Hoy en día aún puedo oler el olor podrido de los cuerpos de aquellos que perecieron en sus casas por miedo al rechazo de los catalanes de antaño. Y es que antes era distinto. La gente proveniente de tierras lejanas era inevitablemente valiente y no se doblegaba ante la inexistente tolerancia de los indígenas locales. Se escondían y hablaban en silencio, en la oscuridad de las velas, vigilantes. Ahora todo ha cambiado. Ahora no ofrecemos ningún tipo de opción a los que se atreven a profanar nuestras ciudades y pueblos. Ahora uno ya no puede escapar de nuestras garras perturbadoras, y todo el mundo es llamado a la obediencia incondicional.

Ahora todo el mundo debe hablar catalán, y no hay sitio donde esconderse. No lo hay.

Y lo digo con orgullo, nos sentimos poderosos y extremadamente superiores. Cada palabra pronunciada de forma incorrecta nos repugna y castigamos aquellos que desobedecen nuestra voluntad.

Y tu, nos deberías temer. Odiar. Admirar.

Algunos Consejos

Nuestros líderes, a modo de muestra de entendimiento con los pueblos hispano-parlantes, han acordado con el estado Español unas visitas guiadas por nuestras tierras. Algo parecido a un safari por tierras africanas, pero en lugar de leones, tenemos a abuelos de Girona con barretina, en lugar de cebras, castellers haciendo un 3 de 10 con forro y manilla y en lugar de ñus, tenemos a chavales rapeando el diccionario de Pompeu Fabra con rimas asonantes.

Algunos consejos para los valientes que quieran visitar nuestra cultura.

  • Recuerda, hablad bajito. Somos radicales e intolerantes por lo que toda muestra de cultura que no sea la nuestra será despreciada, golpeada y exterminada de forma instantánea.
  • Tal vez veas en algún momento una caja encima de una mesa, con una raja en su parte superior y gente haciendo cola tras ella. Te informamos que la gente está injuriando y profanando nuestros más sagrados principios constitucionales. Te invitamos a que les lances piedras y nos avises. Nosotros procederemos a precintar el recinto y a juzgar a los organizadores. Recuerda que somos MUY radicales.
  • Hay unas montañas llamadas Montserrat. Son sagradas y alguien que no conoce nuestro idioma no puede acercarse a menos de 50km. Solo se puede acceder andando y en los alrededores hay perros husmeando en busca de infieles. No tenemos piedad alguna.
  • Una vez al año salimos con nuestras banderas y canciones a hacer apología al terrorismo. Tiendas y contenedores son quemados por familias enteras, mientras los más pequeños son entrenados para la kale borroka (palabras prestadas por nuestros hermanos, el pueblo en las montañas, los Vascos).
  • Si véis a alguien que dice “Goita”, salid corriendo. Es posible que sea uno de nuestros pueblerinos. Se conoce que son los más radicales, suelen ir con una hoz en plan Muerte, y se toman la justícia y la venganza por cuenta propia.
  • No estéis en nuestras tierras más de 3 o 4 dias, o podríais acostumbraros, y esto es algo que ni vosotros ni nosotros queremos.
  • Los niños son entrenados en las escuelas para no entender el castellano, por lo que no les habléis, o podrían reaccionar muy violentamente.

Para que luego digáis que no os avisamos alto y claro…

A usted, estimada Rosa Díaz, gracias por dar conciencia a sus ciudadanos. Su trabajo nos ayuda a todos a estar alerta de nuestra actualidad más verosímil, a que la gente que la lee nos odie y desprecie (aún) más, y con razones. En resúmen, no hace más que contribuir a la construcción de una sociedad con criterio, recursos y conscientes de su propia realidad.

Desde mi más profundo odio de catalán, gracias.

PD: Si comentáis, que sea en catalán. Sino, tendré que utilizar a mis esclavos traductores.

BLDD, Un DD Para Dominarlos a Todos

| Comments

BullshitLess Driven Development

English version

Esta es una carta para tí, pequeño saltamontes programador, que ayer descubriste que un if es una instrucción muy molona que hace que puedas ejecutar un pequeño trozo de código según una condición predeterminada, y que mañana descubrirás muy probablemente qué es una función recursiva, qué es un objeto y que Singleton es un patrón de diseño, o al menos esto dicen por allí…

Esta es una carta para tí, para que te acuerdes de ella en los momentos duros de tu vida como programador y para que busques un punto de partida en esta maravillosa corriente profesional, llena de letras verdes fosforito con significado de victoria, de horas extras impagadas y desagradecidas y de bugs indescifrables, más escondidos que la dignidad de los votantes del PP.

Sonríele a la vida, afortunado. Alabado sea tu futuro!

Y es que hoy, aquí, te quiero contar algunas situaciones que, seguramente, tarde o temprano, y más temprano que tarde, vivirás en alguna de tus futuras hazañas. En estas situaciones hay monstruos, trampas mortales y hasta armas letales. Hay religiones inconexas, dobles morales y lo peor de todo, gilipolleces como para alimentar a medio Congo y sobrar para una cena de navidad donde toda Sierra Leona esté invitada. Barra libre de Moët incluida.

Empecemos con algunas frasecillas del gremio…

Esto está mal

Sí, amigo.

Aunque no lo creas, todo cuanto hagas en tu vida será una verdadera mierda para algunos. Da igual que lleves un día programando, o que tengas la muchas veces inevitable presión de aquellos que te pagan el sueldo, o simplemente que no lo sepas hacer mejor. No importa. Hagas lo que hagas, apestará a perro agusanado.

Y posiblemente lo esté. Posiblemente tu creación será pobre y con muchos fallos, pero tenemos la suerte de que rodeados como estamos rodeados de almas constructivas y caritativas, muy pocas veces un “Está mal” vendrá acompañado de un “Si quieres me siento a tu lado y miramos como puede estar mejor”.

No te ofusques, no estás solo.

Somos la sociedad del “Tu no sabes” y no la del “Creo que puede mejorarse”, y estamos tan acomplejados con nuestras mierdas, que necesitamos poner al principio de nuestras frases un “IMHO” porque sino, puede que se note demasiado que creemos que toda linea de código que no sale de nuestros muñones es basura ipso facto.

Los más educados han decidido enmascarar toda esta realidad con una palabreja de lo más interesante, y querido lector… grábatela en tu memoria desentrenada.

Legacy Code.

Estos de producto…

Otra de las frasecillas que corren por la autopista de lo insultante es “estos de producto, que pesaos con los píxeles” o parecidas, normalmente con tono burlesco y desafiante.

Sí, amigo, un clásico entre compañeros de departamento, muy habituales en cualquier empresa que se precie donde cuiden un poco sus ventas. No todas las empresas son tan modernas y liberales como para dejar a su libre albedrío métricas de ventas y ingresos…

Ah… estos de producto que quieren jodernos la vida con chorradas como píxeles para los frontales, con cambios en la web aparentemente inútiles, o con integraciones con métodos de pago o de transporte. Cuando veas a toda esta gentuza, escúpeles en la cara, porque no nos respetan, a nosotros, a los programadores, a los que hacemos los proyectos que nos piden con tecnologías que desconocemos porque son guasonas y molonas, a los que decidimos que el nuevo proyecto de la empresa se hará con 378 capas distintas, a cada cual más inútil, porque un tal Pepito de los Palotes con sombrero y cuyos fans llevaban el libro de Clean Code tatuado en sus suaves nalgas, dijo que era lo último en Hipsterismo, a pesar de no saber qué estamos haciendo y el porqué lo estamos haciendo. A nosotros que hacemos un formulario en 5 días porque queremos que sea compatible con la GameBoy advance, con la pantallita del microondas y con el termostato de nuestra estufa. A nosotros que nadie nos impide estar todo el día con la nariz enganchada a los grupos online con ciertos parecidos a bacanales.

A nosotros que somos tan responsables.

Te diré un secreto. En voz bajita, que no nos oiga nadie.

Si ellos supieran cada una de las cagadas que hacemos en el código que nos pagan por hacer, o si supieran cada una de las decisiones arquitecturales erróneas que tomamos por el mero hecho de querer molar cantidad, estaríamos todos despedidos. Todos.

Aunque supongo que preferimos decir “Estos de producto…”, aparentar que no tan solo sabemos hacer un foreach, sino que también sabemos hacer el trabajo de media compañía, y seguir con nuestras vidas con la cabeza bien alta, dejando un rastro de Legacy Code, cual rastro en nuestras espaldas.

En mi empresa hacemos…

Esta es perla brillante, el zafiro de las frases, aunque para encontrarla tendrás que esforzarte un poco y dejar que la luz del sol alumbre tu tersa tez para salir de casa y relacionarte con otras personas de otras empresas.

Ánimo.

Y es que descubrirás que todas las otras empresas utilizan lo last de lo last. Mierda de la buena en su stack de tecnologías y droga de la dura en sus últimas incorporaciones (cuando no tienen un auténtico máquina en su departamento de backend, tienen un exfacebook en su departamento de sistemas o un súper crack como CTO llegado de las montañas de los elfos).

Todas las empresas están tan bien dotadas tecnológicamente y con unas plantillas tan extremadamente potentes, que cuando entres en una empresa nueva, nunca, repito, nunca, jamás de los jamases, tendrás la impresión de haber empezado a trabajar en una escabechina llena de cadáveres, pudriéndose durante los últimos 10 años.

Nunca, en absoluto.

Y es que amigo, parece que entre que todo nuestro código es una mierda, y los de producto están todo el día que si ponme este píxel, y ponme este banner, resulta que no tenemos tiempo de hacerlo bien. Pero eh! no es porque seamos todos unos auténticos chapuzas en la mayoría de los casos, no no, es porque no hemos tenido tiempo.

Es que resulta que Uncle Bob dice que…

Rápido y preciso.

  • ¿Está aquí Uncle Bob?
  • ¿Conoce Uncle Bob el proyecto?
  • No, ¿verdad?
  • Pues me importa una mierda lo que diga el tío Bob.

Fin de la discusión.

La clave de todo, BLDD

Dicho esto, verás que el mundo es un lugar inhóspito, lleno de gente con pocas ganas de ayudarte y con muchas de joderte y hundirte, pero aún así tu tienes que hacer un switch porque dadas las circunstancias que sean no puedes o no sabes hacerlo mejor, o tienes que hacer un proyecto con pocos días y por desgracia no puedes hacerlo compatible con el manillar de tu bici.

Te presento, humildemente, el BLDD, abreviación de BullshitLess-Driven Development (otra cosa que tienes que aprender es que aquí escribimos todos con abreviaciones, en inglés aunque estén hablando dos de Albacete, y que debes poner entre frase y frase la palabra Trade-off. Si no haces esto, no serás aceptado por los grandes círculos).

El BLDD es una práctica muy sencilla, basada en el ignorar todas aquellas frecuencias que emitan gilipolleces en directo. Lo que vendría a ser el clásico mandar a esnifar plastidecor picado de toda la vida, pero con un nombre moderno y casual, de estos que nos hacen sentir a nosotros muy top.

Se recomienda primero hacer los tests, y luego implementar el BLDD. Si no lo haces así, eres un mierda.

Esta metodología contrarresta todas las demás que terminan en DD y es aplicable la mayor parte del tiempo útil de tu vida.

  • Que alguien te dice que tu proyecto debería tener tests primero? BLDD.
  • Que alguien te dice que estás muy acoplado a tu FW y solo quieres hacer tu currículum? BLDD
  • Que alguien te dice que tu código es mierda y que él lo hace mejor en DDD? a este le rompes la boca BLDD

Ya ves, funciona cual navaja suiza. Lo bueno de esta práctica es que ten claro que nunca nadie va a decir como debes practicarla. Un sinfín de fórmulas, cada cual más original, pueden formar parte del elenco de posibilidades a la hora de ejecutar el BLDD.

Algunos consejos para terminar

Para finalizar mi cookbook del buen programador, un escueto listado de ideas y miniconsejos de jardinería para que vayas pensando.

  • IMHO, si algún día haces una presentación en público, súbete el libro rojo de DDD contigo, y al que se ponga en la primera fila y se ponga a mirar el móvil o a dormirse, se lo tiras. Le va a doler. Mucho. Y si sigue durmiendo, recuerda que aún tienes de otros colores…
  • IMHO, una conversación se acaba cuando alguien dice la palabra Annotation.
  • IMHO, para tener amigos en Twitter solo tienes que decir “TDD is dead”. Para tener haters, también.
  • IMHO, los tests en tus proyectos es como el paro en españa. Lo importante es el coverage, no la calidad de los cases.
  • IMHO, en Barcelona, de media los developers solemos cambiar de trabajo una vez al año, con subida salarial de forma recurrente. A los 40 años estarás cobrando 120.000 euros y serás un fucking god en 20 lenguajes distintos. Seguirás sin poner bien el puto nombre a una variable y pondrás los comentarios en español.
  • IMHO, a día de hoy, en enero de 2017 es mainstream el Event Sourcing. Si, si, está práctica tan jodidamente útil en todo nuestro sector. Así que calculo que aproximadamente en 2021, en alguna de las empresas en las que trabajes, te encontrarás un conjunto de código intratable, ilegible y profundamente indocumentado fruto de esta modilla. De nada.

Conclusiones

Finalmente decirte que mucha suerte, que aprendas mucho, que leas mucho, que preguntes y enseñes mucho, pero que nunca dejes que nadie te diga como tienes que hacer las cosas (menos si alguien te aconseja que no utilizes Prestashop. En este caso, hazle caso). Ten el suficiente criterio como para aceptar que muchas de las formas de trabajar que escucharás en conferencias, charlas de amiguetes o en hilos de Twitter ni tan solo sirven para tu proyecto.

Trabaja duro, persigue tus objetivos y acuérdate de comprarte muchos libros técnicos, de sacar una foto cada vez que te compres uno y publicar en Twitter algo como “Ya tengo plan para este fin de semana”.

Para todo lo demás, BLDD.

Symfony Catalunya

| Comments

Imagine yourself in front of the Barcelona’s beach in July. It sounds good, right? Then, continue imagining yourself with a great Symfony environment, with a very cold beer, amazing people and even better topics to talk about.

Isn’t it the best plan ever?

Well, if you feel that you need it, then you should continue reading this post…

I’m very very pleased to tell you that this plan is going to happen this summer. The Symfony Barcelona Association is working very hard on this first edition of Symfony Catalunya, an international Symfony event placed in our city. This event is 100% in english and is going to be very focused on how Symfony can help us in our day by day and in our jobs.

Symfony Catalunya 2016

What does it really mean? Let me explain you properly:

  • 0 smoke. This doesn’t mean that we will not talk about new concepts, like React for example, but everything will be constructive and focused on your next day work.
  • New talks. Don’t you feel that all events are populated with same talks year after year? In this event you will find only new talks.
  • Amazing speakers. Speakers are selected because their communication skills. The speaker quality is as important as the talk quality, don’t you think?
  • Community to Community. We will not make any money with that event. All earned gains will be invested in you somehow.
  • 50 euros early bird ticket. Get yours as soon as possible and join us :)
  • Take some breath. 7 talks per day, one after another is never a good option. With 4 talks per day you will be able to enjoy the city and the people.
  • Eat whatever you want, whenever you need. Your ticket doesn’t include food, but the venue is in front of great placed for having lunch and coffee.
  • Lighting talks. If you feel that you have something to show us, bring your 8 minutes speech.

Of course, and because you’re able to buy early bird tickets, we have published 4 of our 8 speakers in our website.

Companies

Are you a company placed in some part of the world? Do you like Symfony? Then this may interest you…

For only 300 euros you will be able to

  • Put your logo everywhere. We will mention you in our media channels at least once.
  • You will be able to add whatever you want in our Conference Attendee bag
  • You will get one free ticket for the conference
  • We will work very very hard to provide you an stand during the conference.
  • You will have the satisfaction to be helping the Symfony Environment, a very important part if you are looking for Symfony developers

We really appreciate companies sponsoring, and we strongly think that should always be that cheaper.

Communities

Are you a PHP or Symfony community? Well, you can help us too by spreading the word. In exchange of that, we will consider you part of our sponsoring group, adding your logo in our list as well.

And is free!

How can you help us? Well, for each new sponsor we have because of you, we will give you one free ticket for the conference. You will be able to raffle this ticket among your community.

Join us

Do you like that? Then…

To be aware of our news, follow our Twitter account (@symfonycat) and say hello :)

You Probably Need Bundle Dependencies

| Comments

This post tries to answer the Magnus Nordlander’s blog post, and to explain why the Symfony Bundle Dependencies is not just a personal project to fulfill my bundles dependencies, but a practice we should implement in all our Symfony bundles as well.

Believe me, I had a big post to explain why people really need this bundle, but I think that you don’t need these words, but a simple and real example.

Magnus, you’re right. Maybe soft dependencies between bundles could be a good option, but you know what? You know why Symfony is one of the biggest PHP projects ever? Because Symfony understands the real user needs, and furthermore, fulfills them the best way.

Why I tell this? Because your “You probably don’t need bundle dependencies” should be “You really need bundle dependencies, but you should work hard to don’t need them anymore”.

Remember, software is real, with real developers, real projects and real needs. We should take it in account as much as we can.

This is my example, from the most used bundle in the world, FOSUserBundle.

1
2
3
4
5
6
7
<service id="fos_user.user_manager.default" class="FOS\UserBundle\Doctrine\UserManager" public="false">
    <argument type="service" id="security.encoder_factory" />
    <argument type="service" id="fos_user.util.username_canonicalizer" />
    <argument type="service" id="fos_user.util.email_canonicalizer" />
    <argument type="service" id="fos_user.object_manager" />
    <argument>%fos_user.model.user.class%</argument>
</service>

I want you to focus on one single line.

1
<argument type="service" id="security.encoder_factory" />

We can discuss about how good or bad this is, but I really ensure you that you will find this in the 99,99% of all bundles. So maybe we need to change our mind and start doing decoupled bundles (not agree in fact, it depends on the case), but right now, hard bundle dependencies (composer and kernel) is something that should be covered the best we can.

About your last question, well, your libraries will require some other libraries and composer will make it happen, with an update and it’s autoloader. But your bundles will probably require dependencies as well, with composer and as well with a library like that, that will tell the Kernel witch bundle should be instanced as well to complain services dependencies.

Your Packages Dependencies

| Comments

  • A component should add as dependency all needed packages to have a complete functionality
  • A bundle should add as dependency as well all these bundles that define other services used in your own service definitions
  • Take care of your version policy. Being too restrictive reduces the compatibility with other packages.

Responsibilities

  • Hi. I’m Marc and I am an open source addict
  • Hi Marc, welcome!

That is a reality in fact. I’m part of this group of people that consider themselves addicts to open source. Big part of our work is created to be shared by everyone, and like Spider-man’s uncle said once… “With great power comes great responsibility”.

But what are those responsibilities we should take care of during our development? What parts of our application should we really take care of and which are more vulnerable over the time? Testing, documentation, clearness of our code, abstraction, extension capabilities… we could talk about them all, and for sure, each one can have enough material for an entire blog or a book.

In that case, I want to expose my personal experiences about what I learned over the time by leading an open source project, several small open source bundles and PHP libraries, and I want to do it by explaining how we should take care of our Symfony bundles or PHP component dependencies.

PHP Component Dependencies

When we talk about PHP components, we talk about framework agnostic packages, only coupled to the language itself, in that case PHP, and to some other libraries. Having said that, we could start by trying to understand how the components and bundles are split in some projects, for example Symfony or Elcodi. Both projects have components and bundles, providing the chance to all frameworks to work with their business logic.

  • So do we place all the business logic in components?
  • Yes. The why of your project is placed in libraries. This will be your service layer, and it should be covered with unit tests.

In regard to dependencies, components should only have dependencies on other components. But how can I discover what packages I really depend on? In that case it’s very simple, so we’re not working with any kind of magic. Because our packages are simple PHP classes, checking the usage of all external classes should be enough to know on which libraries we depend.

In that case, I always write code with use statements, so is much easier to check my external classes usage. Just by checking the first lines of all my classes I can guess what packages I should add in my composer.

1
2
3
4
5
6
7
8
9
10
11
12
namespace Elcodi\Component\User\EventListener;

use Symfony\Component\Security\Core\Event\AuthenticationEvent;
use Doctrine\Common\Persistence\ObjectManager;
use Elcodi\Component\Cart\Entity\Interfaces\CartInterface;
use Elcodi\Component\Cart\Wrapper\CartWrapper;
use Elcodi\Component\User\Entity\Interfaces\CustomerInterface;

/**
 * Class UpdateCartWithUserListener
 */
class UpdateCartWithUserListener

This piece of code makes you depend on four packages at least. Please, don’t focus on the versions, but only on the libraries.

1
2
3
4
5
6
7
8
"require": {
    "php": "*",

    "symfony/security": "*",
    "doctrine/common": "*",
    "elcodi/cart": "*",
    "elcodi/user": "*"
}

Dependencies of Dependencies

Your package must manage ALL of its dependencies, even if they are as well dependencies of your dependencies.

  • Your package A uses B and C.
  • Your package A requires B.
  • Package B requires C.
  • Then, your package A has both B and C. Enough.

Well, that’s not true at all, because you cannot depend never of the dependencies of your dependencies. Maybe now they require a package, but maybe this package won’t be required by your dependency anymore in the future. In that case, even if you still need it, your package will disappear from your vendor folder.

  • Your package A uses B and C.
  • Your package A requires B and C.
  • Package B requires C.
  • Then, your package A has both B and C.
  • Package B does not require C anymore.
  • You still have B and C.

Remember that… Require ALL your dependencies. All of them! That can make the difference.

Adapters

If our application is super decoupled from other libraries, and you have used adapters for those integrations, then things change. Because the use of adapters allows you to decouple from other packages literally, we should find another mechanism to say… hey, maybe you can depend on this package…. Composer proposes that mechanism, by using the suggest section.

1
2
3
"suggest": {
    "some/package": "Use ^2.5 for integration with Some Package"
}

Of course, this is not the only way of doing that. In this example we assume that our package will offer all the adapters implementing an interface, and this is just an option. In my case, I’ve been working for so long with a library called Gaufrette, and I really enjoy the way these kind of packages work.

Some of you could say… oh, but by doing that, then you’re not defining dependencies but only suggestions (sounds the same as saying nothing, in fact), but when we define a requirement is when our package cannot exist without this package. When it is a MUST.

Other kind of implementations don’t take into account the possibility of using the suggest section in composer, because they don’t really solve the dependencies problem. This implementation forces having 1+n packages, the first one containing the interface and the common content, and the other n containing each specific implementation, all of them requiring the first one as a dependency and the specific third-party package.

1
2
3
4
"require": {
    "myself/core": "*",
    "some/package": "^2.5 "
}

This is much more heavy to maintain, and only works if you only offer one port with n adapters in your package. In the case of Gaufrette, this could be a reality, so they only offer one port with n adapters, but of course, having this structure is more difficult to maintain.

Versions

That is a very complex topic. I will not talk about composer, but firstly, I will share some basic concepts that are used a lot when defining dependencies between packages.

  • ~2.5.4 means equal and bigger than 2.5.4 but smaller than 2.6
  • ~2.5 means equal and bigger than 2.5.0 but smaller than 3.0.0
  • ^2.5.4 means equal and bigger than 2.5.4 but smaller than 3.0.0
  • ^2.5 means equal and bigger than 2.5.0 but smaller than 3.0.0

The only thing I can say about that is that if your library aims to be usable by a biggest community as possible, then please consider checking your dependencies deeply, offering as much version-compatibility as possible.

The following composer requirements…

1
2
3
4
5
6
7
8
"require": {
    "php": "5.4.2",

    "symfony/security": "~2.7.3",
    "doctrine/common": "~2.7.3",
    "elcodi/cart": "~1.0.4",
    "elcodi/user": "~1.0.4"
}

are more restrictive than the following ones…

1
2
3
4
5
6
7
8
"require": {
    "php": "^5.3.9",

    "symfony/security": "^2.3",
    "doctrine/common": "^2.3",
    "elcodi/cart": "^1.0",
    "elcodi/user": "^1.0"
}

Of course, you should add requirement compliance as long as they really cover your library needs. If you use Traits, then you should use ^5.4, or if you’re using some Symfony features introduced in a specific version, then you become dependent, at least, on this version

1
2
3
4
5
6
7
8
"require": {
    "php": "^5.4",

    "symfony/security": "^2.7",
    "doctrine/common": "^2.3",
    "elcodi/cart": "^1.0",
    "elcodi/user": "^1.0"
}

Consider as well the compatibility with new major versions, as soon as they confirm their roadmap strategy and feature list. In that case, we could add compatibility with Symfony ^3.0 if we have removed all deprecated elements from old versions, or PHP ^7.0 if we don’t use any ^5.6 deprecated function.

1
2
3
4
5
6
7
8
"require": {
    "php": "^5.4|^7.0",

    "symfony/security": "^2.7|^3.0",
    "doctrine/common": "^2.3|^3.0",
    "elcodi/cart": "^1.0",
    "elcodi/user": "^1.0"
}

This is very important, because if you don’t offer this kind of compatibility, no one using your package will be able to evolve properly, and when I mean someone using your package I mean anyone using any package that, recursively, uses your package.

That can be tons of projects.

Symfony bundle dependencies

Once we have talked about PHP components, let’s talk about Symfony bundles. This is something much more complicated, because a Symfony Bundle is a PHP library that is co-existing in a framework, so it is not as easy to check all our PHP class dependencies.

The question we must ask ourselves when trying to resolve any Symfony bundle dependency map is… What do I really need to make this bundle work in any Symfony project?

Other bundles

This is one of the things Symfony doesn’t solve yet. How can a bundle depend on another bundle, but not only in the composer layer but as well in the application layer?

Well, there is a package for that (remember to star it if turns out useful for you).

Symfony Bundle Dependencies

This package allows you to create bundles with other bundle dependencies very easily. By using this package you will be able to say… okay composer, download this bundles, I need them to instantiate my bundle… and Symfony application, as soon you instantiate my bundle, please, install these other bundles as well before without any need to modify the kernel. Of course, this is only possible if the project works with that package as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use Mmoreram\SymfonyBundleDependencies\DependentBundleInterface;

/**
 * My Bundle
 */
class MyBundle implements DependentBundleInterface
{
    /**
     * Create instance of current bundle, and return dependent bundle namespaces
     *
     * @return array Bundle instances
     */
    public static function getBundleDependencies(KernelInterface $kernel)
    {
        return [
            'Another\Bundle\AnotherBundle',
            'My\Great\Bundle\MyGreatBundle',
            new \Yet\Another\Bundle\YetAnotherBundle($kernel),
            new \Even\Another\Bundle\EvenAnotherBundle($kernel, true),
        ];
    }
}

If the project is not using this package, then the behavior of your bundle won’t change at all.

DIC Services

To resolve all your bundle dependencies you need to take a look as well at your Dependency Injection definition. Let’s imagine we have a bundle with this DIC definition.

1
2
3
4
5
6
7
8
services:

    my_service:
        class: My\Service\Class
        arguments:
            - @twig
            - my_other_service
            - @event_dispatcher

When Symfony tries to resolve this file, it needs as well all the definitions of the arguments (dependencies). The bundles that have these definitions automatically become your bundle dependencies.

The hard work here is to know which bundles have all these service definitions, and that is not always that simple. In that case, for example… Which package has the @twig service? We could think easily… well, twig/twig for sure has the class we are injecting here.

And you’re right, so if any of your classes, in that case My\Service\Class needs a class from the package twig/twig, this package will have to be required by your bundle.

But is that the real answer we need right now? Not at all. The question is not which package provides me with the Twig class, but with the @twig service, and this one is not twig\twig as this is only a PHP library, framework agnostic.

For this reason, we have a bundle called TwigBundle. This bundle, as well as other needed things, creates a new service called twig. This Bundle is required not only because we need the code under our vendor folder, but also because it has to be instantiated when our bundle is instantiated.

1
2
3
"require": {
    "symfony/twig-bundle": "^2.7"
}

If you decide to work with the symfony bundle dependency package, then this code is for you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Mmoreram\SymfonyBundleDependencies\DependentBundleInterface;

/**
 * My Bundle
 */
class MyBundle implements DependentBundleInterface
{
    /**
     * Create instance of current bundle, and return dependent bundle namespaces
     *
     * @return array Bundle instances
     */
    public static function getBundleDependencies(KernelInterface $kernel)
    {
        return [
            'Symfony\Bundle\TwigBundle\TwigBundle',
        ];
    }
}

If you don’t use this package, then you should add the TwigBundle instance in your AppKernel.

Requiring the Framework

How about this services file? What dependencies do you think your package has?

1
2
3
4
5
6
services:

    my_service:
        class: My\Service\Class
        arguments:
            - @event_dispatcher

Some people can say if quickly… the EventDispatcher is a requirement… but we have the same problem as before. The Event Dispatcher is a Symfony component, and has nothing to do with the exposure of their classes in the Symfony Framework dependency injection definition.

Symfony provides as well a bundle called FrameworkBundle. Its mission is, in addition to creating all the working environment for your project (the framework itself), to expose all needed services to the DIC. One of them is the Event Dispatcher from the component (if you check the composer.json file of that bundle you will discover that the symfony/event-dispatcher package is a requirement).

So, some of your bundle services should require as well this bundle.

1
2
3
"require": {
    "symfony/framework-bundle": "^2.7|^3.0"
}

This bundle is almost always required by all bundles (at least, it should), so make sure you’re really tolerant with its version, or you will make your bundle less usable than it could be.

Symfony ^3.0.0

Many packages are actually requiring a very restrictive version of Symfony. This fact has not been a problem during the latest 4 years, but nowadays Symfony v3.0.0 is going to be a reality soon, so all these packages need to make two easy things

  • Check if your bundle introduces a Symfony ~2.8 deprecated feature.
  • If it does, update your bundle to avoid this deprecation
  • Update your requirements to work as well with Symfony ^3.0.

Check that your Symfony requirements then are still valid. For example:

1
2
3
"require": {
    "symfony/framework-bundle": "^2.2|^3.0"
}

Applying this new requirement with Symfony ^3.0 maybe you had to use a new feature that was introduced in Symfony ^2.7.3. In that case, your composer.json is invalid, and if you have covered your class with tests and you run your tests with --prefer-lowest, then you will have some fails there.

You will have to update your dependency properly.

1
2
3
"require": {
    "symfony/framework-bundle": "^2.7.3|^3.0"
}

Development Dependencies

As you may already noticed, development dependencies are not loaded recursively. This means that the require-dev block of your require-dev packages is completely ignored.

In some way, this is great because you can define specifically what packages you need for your development (testing, mostly), without being worried about all the packages that require you.

In some other way, this can be bad… well, yes, you must know exactly all your dependencies for testing (there should be only a few…), so in that case, just make sure you know your application :)

Requiring PHPUnit

And then the question is… should I require PHPUnit or other testing libraries, as well as lints and formatters?

Again, some people will tell you… don’t do that! Your development and testing deployment will require more disk and more resources for composer. Well, sure, but if you depend on the pre-installed PHPUnit version, then you can have some trouble when testing.

1
2
3
4
5
"require-dev": {
    "fabpot/php-cs-fixer": "1.4.2",
    "mmoreram/php-formatter": "1.1.0",
    "phpunit/phpunit": "4.5.0"
},

I really need these versions. No others but these. For example, some lints can add some logic, or even change it. Because we’re responsible for our bundles, components or code, we should trust as less as possible in what other people can do to our dependencies (somehow we really trust a lot of packages by adding the ^2.2 symbol, but in that case we do it not for us but for our users). In testing mode, and because fortunately require-dev block is not recursive, we can perfectly be restrictive with the version we want, and as long as we want/need to change it… just do it :)

Trust

Trusting open source is something you cannot do blindly. Your project is your business, and you need to know that is safe from third party version errors and issues.

If you trust a package, like I do for example in Symfony, then use the semantic version notation in your requirements. Believe that the community will never allow back compatibilities breaks, or they will fix them all as soon as possible when introduced.

If you trust a library because it is tested, but you don’t trust their version policy, then just block the version (knowing that this restricts the compatibility with other packages), or make some push to this community for a really semantic version policy.

If you don’t trust a library at all, then don’t use it. That simple.

Conclusion

So, that’s it.

I highly recommend you, open source lover, to take as much care as possible of your package dependencies. A healthy and useful package is a package used by tons of people. Offer them some confidence and you will get a lot of feedback in return.

Share your work as much as you can, and don’t be afraid of your errors, they will be your biggest reasons for being a better developer day after day, and remember that all of us were inexperienced once.

Error is first step to success

Composer Install in CI

| Comments

If you have a project with a lot of dependencies, then you might now what I am talking about. We all love composer, but we all know as well that, at least with current PHP versions, some composer.json are very heavy to compute and fulfill. All this problems are reduced to time, and some CI engines, like Travis, only allow a finite number of seconds (in Travis case, 20 minutes).

That’s too much!

I found a solution (at least, I thought), but some days ago I saw that was not a solution at all, but a workaround that only sometimes works properly. I will explain exactly what’s the point here.

The problem

My composer.json is very big and composer needs too much time to compute all the dependencies. Reducing dependencies is not an option at all, so the only way of reducing dependencies is by doing some refactoring.

Any final project needs a lot of dependencies, and even if your composer.json file is small, you may need a dependency with a lot of dependencies.

My solution (the bad one…)

This solution is only wrong if you want to test your application under several PHP versions. That’s my case and could be yours…

Well. Computing the real dependencies in my environment seems a great solution, right? I run composer update in my computer, I update the composer.lock version in the repository, and then I only need to do composer install. What I reduce here is the computing time of all recursive dependencies from 20+ minutes to less than 5 minutes.

That’s great!

Why this is a bad solution?

Some projects have decided to increase the minimum PHP dependency only increasing the minor version of the package (and is not wrong, is not BC break). If your project believes in Semantic Version (semver), is usual to find these pieces of composer blocks

1
2
3
4
5
6
"require": {
    "php": ">5.4",
    "symfony/symfony": "^2.7",
    "doctrine/orm": "^2.5",
    "some/package": "^1.3"
}

If my development environment uses PHP 5.5, then I will be able to work with this composer requirements. Great. We update our dependencies, we update our repository with the composer.lock file, and everything should work as expected.

The problem here is that there is an scenario that we are not considering here, and is that for sure, our composer.lock is the result of computing the composer.json file in PHP 5.5, but this doesn’t mean that same dependencies will work as well in PHP 5.4.

Let’s see the some/package composer definition in version 1.3.

1
2
3
4
"require": {
    "php": ">5.4",
    "whatever/whatever": *
}

And then, let’s see the same composer file in version 1.4.

1
2
3
4
"require": {
    "php": ">5.5",
    "whatever/whatever": *
}

As long as we create the composer.lock file in our development environment (remember, with PHP 5.5), we will use version 1.4 of package some/package, but this package version is not compatible with PHP 5.4.

What will happens is that, when we do composer install in your CI, composer will throw an Exception. And that’s always bad news.

The good solution

There’s no good solution at all. In fact, there are only partial solutions, for example generating the composer.lock file with the highest PHP version allowed, but then, if you work with a dependency that forces a PHP version in each version, this won’t work at all.

1
2
3
4
"require": {
    "php": "5.4",
    "whatever/whatever": *
}

So, the only way of doing that is by using composer update in your CI platform. The good point is that you must take care of your composer.json file…

For libraries

If you work with a library, then use the biggest dependency scope. This will allow more users to use your library. Of course, you will increase the final time of composer computation time, but is not your problem at all.

Of course, library composer dependencies should be as small as possible.

1
2
3
4
"require": {
    "php": ">5.4",
    "whatever/whatever": *
}

For final projects

Final projects have the responsibility of reducing that scope, only allowing explicitly highest versions. Of course, final projects can host big composer structures (at least it’s not a bad practice…), so in that case you will have to work harder to reduce that file.

The problem here is not a problem at all, so it has no sense to test your final application under several PHP versions, at least in your CI platform. Just test it under your current PHP version, right?

1
2
3
4
"require": {
    "php": "5.5",
    "whatever/whatever": ^1.5.4
}

Symfony UG, Be Our Friend

| Comments

Symfony Barcelona UG have been looking some sponsors for a while, and we have had a great response from the community. We are so proud and happy about that.

As a User Group, we want to be a community group for all the community, so from today, you can be our UG friend :)

If you are a Symfony UG around the world and you want to be part of it, very easy. Just send an email to symfonybarcelona@gmail.com or just a simple tweet with @symfony_bcn. We will add your logo in our website and you will appear in our next event.

Then, we will be friends :)

Please, share this post on your social networks, and help us making a better world with tons of tiny and cute cats :)

Have a nice week!

Symfony Barcelona Event, September 2015

| Comments

It is a pleasure for me to announce that next September 22nd we will have a great event in Barcelona. I’ve talked many times about this local organization, but this time is pretty different. I’ll explain you.

This year Barcelona hosts the DrupalCon Europe 2015, and this is super exciting. Many people from around the world will visit our great and amazing streets and will attend to a great and big event, related with Drupal, Symfony and other interesting topics, always, related to the Drupal world.

This is very interesting from the point of view of Symfony, because as you may know, new version of drupal, Drupal8, is build using some Symfony components. This is one of the examples I refer when I talk about sharing technologies between PHP projects and when I talk about open source, community and other related topics. We’ve seen these synergies between other PHP projects and Symfony as well with Laravel, eZ Publish, Magento and Joomla (and many more, indeed)

So, this is a call to all the community coming to Barcelona next September 21st. We will host Fabien Potencier, the creator of Symfony, and Lukas Kahwe Smith, an amazing and super active PHP developer, member, for example, of the PHP-FIG group.

http://symfony-barcelona.es

Isn’t it interesting? Indeed, but this is not all!

We are planning to overcome our last assistance record, which is 140 attendees. This time, we want to fill an auditorium of 600 seats and show you what really is Barcelona, and how amazing can be :)

Our sponsors are ready
The community is ready
The organization is ready
Only one thing is missing here…

You!

Join us now for free! and please share this post to allow everyone to know about it!

EventListeners as Collectors in Symfony

| Comments

Some of my concerns during the last couple of years have been how to collect data from all installed bundles using available tools in Symfony packages. I say concerns because I don’t really know if is there a tool for that.

Some people have told me that the EventDispatcher component can do this work greatly, but then I have the same question once and again… is this component designed for such?

Let’s review some tiny concepts here.

Event immutability

Try to think what really is an event. Something that happens. For example, I wake up. Once I wake up, an event is dispatched called mmoreram.wake_up. This event, of course, is immutable. Nothing can change the fact that I woke up, so the event should be treated as an immutable object, with only reading actions.

One single property of the event is injected once is created. Did I wake up rested enough for a new crazy day with all cool guys from my office?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
namespace Mmoreram;

use Symfony\Component\EventDispatcher\Event;

/**
 * Marc woke up event
 */
class MmoreramWakeUpEvent extends Event
{
    /**
     * @var boolean
     *
     * Marc woke up rested
     */
    private $rested;

    /**
     * Construct method
     *
     * @var boolean $rested Marc woke up rested
     */
    public function __construct($rested)
    {
        $this->rested = $rested;
    }

    /**
     * Get if Marc is rested enough
     *
     * @return boolean Marc is rested enough
     */
    public function isRested()
    {
        return $this->rested;
    }
}

Of course, no one should be able to change the value of rested, because no one has the power to change the fact I woke up tired this night.

The main intention of an event is notify the world that something just happened, so any extra implementation changing this paradigm should be avoided in order to not corrupt the real meaning of the component.

Said that, and before continuing with the post… a question related to this topic. Just make sure that you can take some time to think about that.

If we talk about decoupling between components… is the concept of priority helpful? If any actor must know the priorities of all listeners in order to know its own… then can we consider that all event listeners are really decoupled between them? And how bad is that?

Collector

Let’s figure out that the system need to collect some feelings when I wake up. Let’s figure out as well that we don’t really care about how these feelings are sorted, so the problem of priority is not a problem anymore: we can ignore it completely.

We can change our event with this new implementation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
namespace Mmoreram;

use Symfony\Component\EventDispatcher\Event;
use Mmoreram\Feeling;

/**
 * Marc woke up event
 */
class MmoreramWakeUpEvent extends Event
{
    /**
     * @var boolean
     *
     * Marc woke up rested
     */
    private $rested;

    /**
     * @var Feeling[]
     *
     * Array of feelings
     */
    private $feelings;

    /**
     * Construct method
     *
     * @var boolean $rested Marc woke up rested
     */
    public function __construct($rested)
    {
        $this->rested = $rested;
        $this->feelings = [];
    }

    /**
     * Add new feeling
     *
     * @param Feeling $feeling New feeling to be added
     *
     * @return $this Self object
     */
    public function addFeeling(Feeling $feeling)
    {
        $this->feelings[] = $feeling;

        return $this;
    }

    /**
     * Get if Marc is rested enough
     *
     * @return boolean Marc is rested enough
     */
    public function isRested()
    {
        return $this->rested;
    }

    /**
     * Get all feelings
     *
     * @return Feeling[] Set of feelings
     */
    public function getFeelings()
    {
        return $this->feelings;
    }
}

Of course, in our domain we must dispatch this event one I really wake up (for example a service called MmoreramVitalActions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
use Mmoreram\MmoreramWakeUpEvent;

/**
 * Marc vital actions
 */
class MmoreramVitalActions
{
    /**
     * Marc wakes up
     *
     * @return Feeling[] Set of feelings resulting of the action of waking up
     */
    public function wakeUp()
    {
        $rested = $this->didMarcRestedProperly();
        $eventDispatcher = new EventDispatcher();
        $event = new MmoreramWakeUpEvent($rested);

        $dispatcher
            ->dispatch(
                'mmoreram.wake_up',
                $event
            );

        return $event->getFeelings();
    }

    /**
     * Get if Marc rested properly
     *
     * @return boolean Marc rested properly
     */
    private function didMarcRestedProperly();
}

As you can see, after dispatching the event you should be able to get all collected feelings. This means that the one in charge to fulfill this information related to my feelings should be any event listener interested in adding it’s own related feeling.

For example, an Event Listener will have the responsibility to add a feeling related to the temperature of my room.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use Mmoreram\MmoreramWakeUpEvent;

/**
 * Marc wake up event listener related to temperature.
 * This class is intended to add a feeling depending on local temperature
 */
class TemperatureMmoreramWakeUpEventListener
{
    /**
     * Marc wakes up listener
     *
     * @param MmoreramWakeUpEvent $event Marc wake up event
     *
     * @return $this Self object
     */
    public function addTemperatureFeeling(MmoreramWakeUpEvent $event)
    {
        $feeling = $this->getTemperatureFeeling();
        $event->addFeeling($feeling);

        return $this;
    }

    /**
     * Get feeling related to the temperature
     *
     * @return Feeling Feeling related to temperature
     */
    private function getTemperatureFeeling();
}

Of course, you must add this event listener using tags in the Dependency Injection Symfony configuration.

Using tags for our listeners definition

At this point, you can see that maybe this is useful. This is a very easy and fast collector implementation, but not enough good. The event is not immutable anymore and you can change if from any event dispatcher, very far from the real intention of the component.

Solution

I am using this approach in order to be as much pragmatic as possible. Of course this works properly by adding an extra definition and documentation layer, but I wonder if other people is concerned about that in Symfony.

I don’t really think that yet another component called Collector would be necessary at all unless there is an abstraction between both components (they share some common things related to the fact of broadcasting and subscribing).

Of course, again, simple theory and personal thoughts brought to the community. I will continue using this approach even knowing that should be solved using another one as long as people understand it and is easy to work with.

Feedback and people thoughts will be appreciated, as always :)