Comentarios, discusiones, notas, sobre tendencias en el desarrollo de la tecnología informática, y la importancia de la calidad en la construcción de software.
domingo, agosto 29, 2021
sábado, junio 27, 2015
Una guía de trabajo con Plex
STOP Coding - Start ArchitectingLa primera regla que un nuevo desarrollador en Plex debe asumir, es que debe escribir la menor cantidad de código posible: olvidarse de escribir líneas de código, y pensar, pensar el modelo de datos y relaciones, luego estudiar cómo abstraer y explotar patrones existentes, y sólo luego escribir código, sólo lo que es estrictamente necesario. "Whenever there is a hard job to be done I assign it to a lazy man; he is sure to find an easy way of doing it"
Plex development is essentially a three-step process involving Data Modeling, Pattern Matching and Customization. There are no shortcuts, each step must be adhered to achieve the goals. Missing a step may seemingly achieve a short term solution but in the medium and long term the solution will surely decay far quicker than it should have. The mindset required to use plex effectively is one of:
- Object oriented approach to application design to eliminate the need to code repeatable elements of applications
- Working at a level of abstraction rather than at the ‘nuts and bolts’ level, probably just saying the first point again but this can’t be over stressed the importance to think this way instead of coding procedural code line after line
- Model-based and pattern-based approach to increased application quality and flexibility
- Multiple inheritance is a key part of the way applications are developed in CA Plex therefore leveraging the full value of a site’s existing patterns
- Encapsulation so that function interfaces contain only the attributes pertinent to the use of the function
- An application should be separated into separate layers/tiers, Functionality should be strictly separated into data access, business logic and presentation logic, as this promotes the consistency of the application as well as the possibilities to reuse functionality.
martes, abril 07, 2015
Diez reglas para recordar (y seguir...)
DRY (Don't repeat yourself)Y volviendo sobre la idea de su aplicabilidad en Plex, sin duda lo es. En algunos casos fácilmente entendible, (Favor Composition over Inheritance, Encapsulate What Changes, DRY, Favor Composition over Inheritance) y en otros casos, después de luchar contra la vía fácil de hacer las cosas (Programming for Interface not implementation). Solo veo difícil implementar Dependency Injection. Y cuando me refiero a aplicabilidad, lo hago a nivel del modelo, no a nivel del código generado, donde su aplicabilidad está asegurada.
Our first object oriented design principle is DRY, as name suggest DRY (don't repeat yourself) means don't write duplicate code, instead use Abstraction to abstract common things in one place. If you have block of code in more than two place consider making it a separate method, or if you use a hard-coded value more than one time make them public final constant. Benefit of this Object oriented design principle is in maintenance. It's important not to abuse it, duplication is not for code, but for functionality . It means, if you used common code to validate OrderID and SSN it doesn’t mean they are same or they will remain same in future. By using common code for two different functionality or thing you closely couple them forever and when your OrderID changes its format , your SSN validation code will break. So beware of such coupling and just don’t combine anything which uses similar code but are not related.
Encapsulate What Changes
Only one thing is constant in software field and that is "Change", So encapsulate the code you expect or suspect to be changed in future. Benefit of this OOPS Design principle is that Its easy to test and maintain proper encapsulated code. If you are coding in Java then follow principle of making variable and methods private by default and increasing access step by step e.g. from private to protected and not public. Several of design pattern in Java uses Encapsulation, Factory design pattern is one example of Encapsulation which encapsulate object creation code and provides flexibility to introduce new product later with no impact on existing code.
Open Closed Design Principle
Classes, methods or functions should be Open for extension (new functionality) and Closed for modification. This is another beautiful SOLID design principle, which prevents some-one from changing already tried and tested code. Ideally if you are adding new functionality only than your code should be tested and that's the goal of Open Closed Design principle. By the way, Open Closed principle is "O" from SOLID acronym.
Single Responsibility Principle (SRP)
Single Responsibility Principle is another SOLID design principle, and represent "S" on SOLID acronym. As per SRP, there should not be more than one reason for a class to change, or a class should always handle single functionality. If you put more than one functionality in one Class in Java it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality, which require another round of testing to avoid any surprise on production environment.
Dependency Injection or Inversion principle
Don't ask for dependency it will be provided to you by framework. This has been very well implemented in Spring framework, beauty of this design principle is that any class which is injected by DI framework is easy to test with mock object and easier to maintain because object creation code is centralized in framework and client code is not littered with that.There are multiple ways to implemented Dependency injection like using byte code instrumentation which some AOP (Aspect Oriented programming) framework like AspectJ does or by using proxies just like used in Spring. See this example of IOC and DI design pattern to learn more about this SOLID design principle. It represent "D" on SOLID acronym.
Favor Composition over Inheritance
Always favor composition over inheritance ,if possible. Some of you may argue this, but I found that Composition is lot more flexible than Inheritance. Composition allows to change behavior of a class at runtime by setting property during runtime and by using Interfaces to compose a class we use polymorphism which provides flexibility of to replace with better implementation any time. Even Effective Java advise to favor composition over inheritance.
Liskov Substitution Principle (LSP)
According to Liskov Substitution Principle, Subtypes must be substitutable for super type i.e. methods or functions which uses super class type must be able to work with object of sub class without any issue". LSP is closely related to Single responsibility principle and Interface Segregation Principle. If a class has more functionality than subclass might not support some of the functionality ,and does violated LSP. In order to follow LSP SOLID design principle, derived class or sub class must enhance functionality, but not reduce them. LSP represent "L" on SOLID acronym.
Interface Segregation principle (ISP)
Interface Segregation Principle stats that, a client should not implement an interface, if it doesn't use that. This happens mostly when one interface contains more than one functionality, and client only need one functionality and not other.Interface design is tricky job because once you release your interface you can not change it without breaking all implementation. Another benefit of this design principle in Java is, interface has disadvantage to implement all method before any class can use it so having single functionality means less method to implement.
Programming for Interface not implementation
Always program for interface and not for implementation this will lead to flexible code which can work with any new implementation of interface. So use interface type on variables, return types of method or argument type of methods in Java. This has been advised by many Java programmer including in Effective Java and head first design pattern book.
Delegation principle
Don't do all stuff by yourself, delegate it to respective class. Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two object for equality we ask class itself to do comparison instead of Client class doing that check. Benefit of this design principle is no duplication of code and pretty easy to modify behavior.
Plex, como otros productos, admite distintas interpretaciones, distintas formas de desarrollar. Aplicar principios de OOD permite explotarlo en forma más productiva, potenciando sus características. Luchar por no usar una hoja de ruta rutinaria favorece resultados consistentes y duraderos.
domingo, febrero 22, 2015
James Ward sobre Java
Un punto importante, pero recordado sólo con el propósito de que lea completa la reflexión de James Ward, que lo merece.Monolithic Releases Suck
Unless you work for NASA there is no reason to have release cycles longer than two weeks. It is likely that the reason you have such long release cycles is because a manager somewhere is trying to reduce risk. That manager probably used to do waterfall and then switched to Agile but never changed the actually delivery model to one that is also more Agile. So you have your short sprints but the code doesn’t reach production for months because it would be too risky to release more often. The truth is that Continuous Delivery (CD) actually lowers the cumulative risk of releases. No matter how often you release, things will sometimes break. But with small and more frequent releases fixing that breakage is much easier. When a monolithic release goes south, there goes your weekend, week, or sometimes month. Besides… Releasing feels good. Why not do it all the time?
Moving to Continuous Delivery has a lot of parts and can take years to fully embrace (unless like all startups today, you started with CD). Here are some of the most crucial elements to CD that you can implement one-at-a-time:
There are a ton of details to these that I won’t go into here. If you’d like to see me expand on any of these in a future blog, let me know in the comments.
- Friction-less App Provisioning & Deployment: Every developer should be able to instantly provision & deploy a new app.
- Microservices: Logically group services/apps into independent deployables. This makes it easy for teams to move forward at their own pace.
- Rollbacks: Make rolling back to a previous version of the app as simple as flipping a switch. There is an obvious deployment side to this but there is also some policy that usually needs to go into place around schema changes.
- Decoupled Schema & Code Changes: When schema changes and code changes depend on each other rollbacks are really hard. Decoupling the two isolates risk and makes it possible to go back to a previous version of an app without having to also figure out what schema changes need to be made at the same time.
- Immutable Deployments: Knowing the correlation between what is deployed and an exact point-in-time in your SCM is essential to troubleshooting problems. If you ssh into a server and change something on a deployed system you significantly reduce your ability to reproduce and understand the problem.
- Zero Intervention Deployments: The environment you are deploying to should own the app’s config. If you have to edit files or perform other manual steps post-deployment then your process is brittle. Deployment should be no more than copying a tested artifact to a server and starting it’s process.
- Automate Deployment: Provisioning virtual servers, adding & removing servers behind load balancers, auto-starting server processes, and restarting dead processes should be automated.
- Disposable Servers: Don’t let the Chaos Monkey cause chaos. Servers die. Prepare for it by having a stateless architecture and ephemeral disks. Put persistent state in external, persistent data stores.
- Central Logging Service: Don’t use the local disk for logs because it prevents disposability and makes it really hard to search across multiple servers.
- Monitor & Notify: Setup automated health checks, performance monitoring, and log monitoring. Know before your users when something goes wrong.
domingo, junio 15, 2014
El objeto CDO y Office: ¿obsolescencia programada?
Posiblemente el API de MAPI haya sido intermediado por el uso de CDO ampliamente desde su aparición; bien definido, bien documentado, consistente, capaz de ser invocado desde casi todos los lenguajes ejecutables en Windows, y particularmente desde las propias implementaciones de Microsoft para el lenguaje de propósito especial de Office (VBA).
Sin embargo, a partir de Office 2010, nos encontramos que CDO no es instalado, y es desaconsejado su uso para interactuar con Office a partir de esta versión, debido a cambios de arquitectura en la suite de oficina:
Microsoft Outlook 2010 and later versions include many architectural changes to the client-side MAPI subsystem. Of particular concern are scenarios in which Outlook is configured to use multiple Exchange accounts. Also, CDO 1.2.1 is a 32-bit client library and will not operate with 64-bit versions of Outlook. Given all these factors, CDO 1.2.1 is not supported for use with Outlook 2010 or Outlook 2013, and we do not recommend its use with Outlook 2010 and later versions.¿Podemos considerar esta decisión una violación de los principios de arquitectura del modelo COM? Una vez más, el concepto de compatibilidad y continuidad del soporte de Microsoft opta por la vía rápida: se elimina su instalación, se ralea la información y documentación a partir de ahora "legacy", y se recomienda calurosamente el cambio a la nueva versión. Microsoft tiene una solución a su patrimonio de funciones construidas usando CDO:
Programs that use CDO should be re-designed to use other Application Programming Interfaces (APIs) instead of CDO (...) Developers should use the Outlook 2010 and later object model instead of CDO 1.2.1. Also, developers can still use Extended MAPI (which requires unmanaged C++) in some scenarios where CDO was required. However, if it is possible, we generally recommend that the Outlook object model be used instead of Extended MAPI. Microsoft product support can help developer customers migrate custom programs from using CDO 1.2.1 to using other APIs. However, Microsoft will not provide support for any scenarios in which CDO 1.2.1 is used with Outlook 2010 or Outlook 2013.Simple, entonces: busque todos los casos en que usara CDO, y rediseñelos para usar el modelo de objeto Office. Justo cuando Microsoft está en transición entre Win32 y WinRT, para descubrir que dentro de un par de años WinRt determina otro modelo de objeto, y, sin más trámite, todo su patrimonio sea discontinuado de nuevo.
Sin duda usted podrá seguir usando CDO, en un marco limitado, recurriendo a modificaciones de la instalación, a condición de cómo administre su instalación de Exchange (vea el punto More information en la página del anuncio de Microsoft). Pero no será soportado, y cada día encontrará menos documentación para arreglárselas por su cuenta. Si lo va a seguir utilizando, tome una medida de precaución: conserve como documento off line todo lo que pueda conseguir todavía de guía de referencia y soporte de Microsoft. Como en muchos casos, pronto encontrará que las (escasas) referencias que se conserven, lo conducirán a páginas muertas. ¿CDO funciona? digamos que sí. Lo que ha cambiado es Office, y la compatibilidad hacia atrás parece que es secundaria: cambie de modelo de API. La mejor explicación acerca de las razones del conflicto de versiones la he encontrado en lo analizado por Matt Stehle, en los MSDN blogs. Matt apunta a la existencia de dos modelos de manejo de memoria: el de MAPI/CDO, y el de .NET, que pueden producir intermitentes problemas de asignación de memoria:
MAPI has its own memory management model that conflicts with and is incompatible with the .NET runtime. This the primary reason that MAPI and CDO 1.21 are not supported running in a .NET process. The common symptoms you will see are seemingly random Access Violations and very often memory leaks (especially with CDO 1.21). There is no methodology for avoiding or managing these symptoms by using interop libraries or managing references in a particular fashion in your .NET code – it just won't work.Matt se extiende sobre el alcance de éste conflicto, reconociendo que realmente sólo a partir de Office 2007 existen mejores reemplazos de CDO, y que por lo demás, ambos serán excluyentes (The simple answer is you either need to not use .NET or not use MAPI or CDO 1.21). Puede leer la nota completa de Matt en su blog. No se arrepentirá, especialmente si sigue la acotación que apunta Matt a lo que Patrick Reehan dice acerca de qué significa "no soportado" para Microsoft.
The trap is that CDO 1.21 and .NET can "appear" to work and you can get pretty far in your dev cycle before you run into problems. Many times we see this come up in soon after a solution is released to production, in late cycle performance testing, or in a pilot program. Opening a critical case with Microsoft when you have end users complaining of crashes or project managers short on budget is not a good time to find out that your solution is unsupportable.
En nuestro caso, el impacto sería reducido (por otra parte en ningún caso los servidores de Exchange han provocado conflictos todavía), porque CDO/MAPI están sumamente encapsulados, y no conviven procesos .NET con CDO. Todo nuestro manejo de mensajería pasa por un solo objeto, y las interfases entre un modelo y este objeto son exclusivamente de datos, sin ningún condicionamiento técnico. Bastará con redefinir las actuales llamadas, adecuándolas a los nuevos requerimientos, y recompilarlo y distribuirlo. No hará falta tocar nada más. ¿Pero esto es así en todos los casos? seguramente no, y probablemente en muchas empresas habrá (o hubo) trabajo inesperado.
jueves, febrero 20, 2014
Tropezando en software mal terminado
My impression is that up to about ten years ago most companies were still trying, in good faith, to put out a good product. But now many of them, especially the biggest ones, have completely given up. One sign of this is the outsourcing trend. Offshore companies, almost universally, are unwilling and unable to provide solid evidence of their expertise. But that doesn’t matter, because the managers offering them the work care for nothing but the hourly rate of the testers. The ability of the testers to test means nothing. In fact, bright inquisitive testers seem to be frowned upon as troublemakers.
(...) This is my Quality is Dead hypothesis: a pleasing level of quality for end users has become too hard to achieve while demand for it has simultaneously evaporated and penalties for not achieving it are weak. The entropy caused by mindboggling change and innovation in computing has reached a point where it is extremely expensive to use traditional development and testing methods to create reasonably good products and get a reasonable return on investment. Meanwhile, user expectations of quality have been beaten out of them. When I say quality is dead, I don’t mean that it’s dying, or that it’s under threat. What I mean is that we have collectively– and rationally– ceased to expect that software normally works well, even under normal conditions. Furthermore, there is very little any one user can do about it.Esta incómoda afirmación de un especialista, se puede comprobar a diario, a cualquier nivel. Un incidente esta semana pasada me lo hizo recordar: migraba en Eclipse la versión de una librería que uso, a su último fix (esto sólo ya daría para hablar largo sobre políticas de entrega de producto). Ésto, mientras a la vez migraba de sistema operativo y máquina: demasiados frentes abiertos; Windows 7 a su último nivel crítico de actualizaciones, Visual Studio y Java instalados por primera vez en la máquina; en este último caso, a las instalaciones de JRE de Java 6 y Java 7, agregamos la instalación del JDK de JEE 6, tomando la última versión ofrecida por Oracle en su sitio de descargas para JEE 6: la que se instala con Java SE modificación 29.
Haciendo las primeras pruebas de funcionamiento de Eclipse con el proyecto en que trabajaba, encontré que la primera aplicación que probaba fallaba a poco de iniciarse. Después de algo de búsqueda, el problema quedó localizado en la primera llamada a Microsoft SQL Server, con la particularidad de que la llamada al driver sqljdbc4.jar recibía el control, y comenzaba la descarga de clases necesarias, hasta detenerse en una llamada en particular, sin provocar una excepción: simplemente la aplicación se colgaba sin aviso de ningún tipo, ni siquiera en el visor de eventos de Windows. La primera acción fue comparar la carga de clases en las dos máquinas involucaradas (la que estaba migrando, y la de destino, nueva), y tratar de asegurar que no se estuviera solicitando una clase que faltara en el jar cargado. Una búsqueda en todas las carpetas encontró no menos de seis copias del jar, pero ninguno de ellos podría haber entrado en conflicto, y la copia que debiera llamarse estaba en la ruta esperada. A pesar de que hubo que hacer algo de limpieza del número de copias y de sus rutas, este no era el problema. Por lo tanto, decidí comenzar una búsqueda de incidencias entre Java, JEE, servlets, Microsoft SQL Server jdbc, y/o SQL en general. A poco de revisar, apareció una consulta en StackOverflow, que vinculaba la incidencia a la modificación 29 de Java SE. Siguiendo su discusión, llegué al caso en Oracle: JDK-7103725 : REGRESSION - 6u29 breaks ssl connectivity using TLS_DH_anon_WITH_AES_128_CBC_SHA. En la evaluación del impacto del fallo, se afirma: "The more obvious impact of this bug is to the MS JDBC Driver and MS SQL Server".
Tanto los comentarios en StackOverflow como la propia descripción del problema corregido coincidían en sus efectos con el que nos afectaba. De modo que, siguiendo las líneas recomendadas allí, descargamos una versión posterior de Java SE, la última disponible para Java 6, la modificación 45. Reemplazada la versión, no hubo más que arrancar Eclipse y la aplicación para encontrar todo trabajando normalmente...
Ahora, atemos nuestro percance con lo que James Bach dice más arriba: cuando instalábamos esta máquina, buscamos el paquete de JEE 6 en su sitio oficial, donde JEE 6 con el sdk de Java SE m29 es una de las opciones disponibles. Si bien la elección entre varias opciones fue nuestra, no existía ninguna advertencia de dificultades con JDBC (!) o SQL Server ni su documentación advierte que existe un problema, y que para resolverlo...se debe cambiar de versión. ¿Qué clase de entrega de un producto es una que no dice que fallará bajo ciertas circunstancias, para más, bastante comunes, cuando eso ya fue detectado? ¿Qué protocolo de comunicación existe entre quienes desarrollan el producto (JEE) y quienes lo mantienen (Java Community)?
Este es sólo un minúsculo ejemplo; sólo en el proceso de resolver este inconveniente podría hablar de varias imperfecciones de todo tipo, tan simples como insólitos resultados de la búsqueda de un objeto en el sistema de archivos (fallo en Windows 7), o la imposibilidad de usar las herramientas de desarrollador en Internet Explorer. O encontrar que un fix produce otro fallo que requiere otro fix al día siguiente...y otro más un día después.
En una época en que los métodos ágiles predominan, conjeturo que algo de responsabilidad les corresponde: reducir los tiempos de entrega, simplificar las metas de cada release, creo que también conducen a este estado de permanente falta de terminación.
domingo, febrero 03, 2013
Wikipedia y la programación
miércoles, diciembre 26, 2012
¿Java Legacy?
[ dice Mazen Rawashdeh, VP de Infrastructure Operations Engineering en Twitter]Part of the reason Twitter was able to sustain this level of traffic was down to a set of changes the company has been making to their infrastructure, including, as InfoQ previously reported, a gradual shift away from Ruby to a set of services written in a mixture of Java and Scala and running on the JVM.InfoQ historia este proceso gradual de migración:
Twitter was at one time thought to be the largest Ruby on Rails shop in the world, and has made a substantial investment in its Ruby stack, going as far as developing its own generational garbage collector for Ruby called Kiji, which, unlike the standard Ruby collector, divides objects into generations and, on most cycles, will place only the objects of a subset of generations into the initial white (condemned) set.Respecto a los clientes móviles, Rawashdeh dice: As part of our ongoing migration away from Ruby we've reconfigured the service so traffic from our mobile clients hits the Java Virtual Machine (JVM) stack, avoiding the Ruby stack altogether.
In 2010, however the firm announced that it was shifting some of its development focus. For the front-end the firm followed the HTML5 trend of shifting rendering code into browser-based JavaScript, and, in so doing, it ceased to gain much benefit from Rails' templating model for building web pages. Then, citing both performance and code-encapsulation as drivers, the engineering team re-wrote both its back-end message queue and tweet storage engine in Scala.
Respecto a su motor de búsqueda, también el cambio se inclinó por java: in 2011 the engineering team announced that they had replaced the Ruby on Rails front-end for search with a Java server they called Blender. This resulted in a 3x drop in search latencies.
En años anteriores se comenzó a hablar de Java como un lenguaje legacy, y de su toma por parte de Oracle, como su sentencia de muerte. Sin embargo, ha corrido agua, y la muerte no se produce: Java 7 en marcha, y preparativos para Java 8. En mi experiencia personal, con un uso más extenso de Java, observo estabilidad, confiabilidad, y buena performace. Cada vez que he tenido problemas con la JVM se ha debido a fallos en la preparación de funciones, y he podido contar con buena ayuda de la consola de java en primer lugar, y de la documentación y la buena capacidad de manejo de errores. Tanto como soporte servidor, como en funciones cliente, la respuesta ha sido normal. Como máquina servidora para aplicaciones web basados en HTML + Javascript, su servicio es transparente y robusto. Y esto, sin contar con su ubicuidad: en cierto modo, "multiplataforma" en mi caso implica Java. En fin, mi experiencia es coincidente con esto dicho en InfoQ.
domingo, junio 17, 2012
La exagerada muerte del RPG
Antes que nada, quiero destacar lo que Scott Klement ha dicho al respecto: cuando hoy se habla de RPG, se debe hablar de RPG IV, o ILE. Desde este punto de vista, el lenguaje no sólo se muestra muy activo, como pudiera decirse también de otros muertos de buena salud (COBOL) sino que además ha vivido una importante evolución respecto a sus antecesores (III, II) que lo convierten en una herramienta poderosa en el marco del iSeries. Como Scott ha dicho, decretar la muerte del RPG (ILE), es como declarar muerto al iSeries...algo que su competencia desearía, y está lejos de suceder (salvo que IBM esté dispuesta al suicidio).
Lo que sigue, son algunos puntos destacados en esta discusión:
Nathan Andelin sobre OOP:
Saying that RPG isn't object oriented is a red herring. OO is generally characterized by "encapsulation", "polymorphism", and "inheritance". By far the most prominent characteristic of OO is encapsulation, and nothing meets that characteristic better than ILE RPG.La referencia de Andelin a RPG y OOP es más extensa, y probablemente sea mejor ver pos separado. Invito por ahora a seguir su explicación, distribuída en más de una de sus intervenciones.
It's not that RPG is not object oriented. It's just that polymorphism and inheritance are not as fully implemented in the compiler as in a language like Java. However, RPG programmers are free to implement their own interfaces that support polymorphism and inheritance to the degree of their choice. I've written about that in the past and posted sample code over the years.
El mismo, sobre la potencia del RPG asociado al iSeries:
Our user interfaces are written in HTML, CSS, and JavaScript, while the majority of our server-side code is RPG. Following are some reasons one might consider using RPG for web applications:Giuseppe Tintor, sobre el uso de RPG en la capa servidora:
RPG has more efficient database interfaces. Most applications NEED record level access as well as SQL for database I/O. RPG uses less CPU and I/O, has less latency, and performs much better than more mainstream languages, etc.
RPG web applications can maintain state just like 5250 applications, which takes a burden off programmers as well as garbage collectors. Users can even launch multiple instances of the same application without worrying about the state of each. Users can end jobs and free resources by clicking an Exit link.
You can launch RPG programs that perform database I/O and browser I/O and run under IBM i user profiles. You can use IBM i security interfaces to specify authorities of each. User IDs are automatically recorded in journal entries for changes made to IBM i databases and other objects.
RPG jobs can take advantage of IBM i workload management; utilizing subsystems, memory pools, run priorities, time slices, library lists, job descriptions, job logs, output queues, spool files, etc.
With RPG you can activate thousands of IBM i jobs to support thousands of concurrent users where each job can have its own runtime environment. Contrast that with so called “modern” languages that run under environments where you have to set up a separate virtual machine for each environment.
Workload management under IBM i is much more advanced and offers much more control than managing workloads with LPARS and comparable virtual machines. A hypervisor doesn't know the characteristics of workloads that run under a VM that it's managing. It may know whether a VM is requesting resources or not but it has no understanding of priority. IBM i is more effective at managing workloads.
Rather than setting up multiple virtual machines for separate organizations, or for separate development, test, or production environments, you can use separate subsystems, and separate library lists. RPG saves programming time, system administration, and computer resources, which ultimately saves money.
I use Java to write web application (jsp, servlet) but the databse access is done through RPG programs only; RPG il called from Java using pcml interface so I'm sure that the database is completly closed to external users and nobody can run sql, query or excel inquiries on files. None is aware that behind a web page there is RPG and none notice performance problems! I think that RPG is the perfect tool to manage database access on AS/400.Una línea de discusión abierta sobre la capacidad del iSeries de sostener múltiples trabajos simultáneos toca no sólo al RPG, sino al soporte del propio sistema operativo; la comparación con un servidor Windows puede incomodar a administradores de éste servidor. A propósito de una pregunta de uno de los participantes (Is the concept of an active job in the IBM i the same as the concept of an “active job” in a PC server? As I understand it, one user in the IBM i is at least one job. In the PC world, one job can accommodate numerous users – dependent on the PC server’s resources, of course. (...) Tens of thousands? I know the IBM i QMAXJOB shipped value is 163520 but do you have experience with your system reaching that many users (tens of thousands) ? If I’m not mistaken, the client I work for only has a little more than 1500 users. Even then, their IBM i which is at V7R1 is already experiencing performance degradation. (I think I need to ask my manager about that again.) [preguntado a Andelin por Allan Roberto Garcia]):
You asked, "Is the concept of an active job in the IBM i the same as the concept of an “active job” in a PC server?"La discusión aún continúa. Sólo he destacado algunos puntos. Otros, tales como el modelo OOP, o el desarrollo de aplicaciones web contra funciones servidoras RPG están desarrolladas, ejemplificadas, y ofrecen excelentes perspectivas. Una gran respuesta a quienes dan por muerto lo que no conocen.
It's a good thing that I reread your question a couple times and put some thought into it because I think I profoundly misunderstood it the first time.
At first, I thought you might be talking about the concept of a "process" under IBM i vs. a "process" under Windows. When you open Task Manager under Windows and navigate to the Processes tab you see a screen that looks fairly similar to the WRKACTJOB display under IBM i. Right?
Windows Task Manager shows you a list of .exe files "running". WRKACTJOB shows a list of "active jobs" under IBM i. I think you would find a lot of similarities between what an "active job" might be doing under IBM i, and what a Windows .exe might be doing. Wouldn't you agree?
One key difference would be that you would NEVER see tens of thousands of running .exe files under Windows. The runtime environment would be destabilized long before that could occur. But under IBM i, tens of thousands of "active jobs" would NOT be a problem.
So, while there may be many similarities between the work being done by Windows .exe files and IBM i active jobs, the design of the runtime environments are profoundly different. Windows cannot support complex workloads reliably. Complex workloads under Windows must be divided between multiple physical or virtual machines in order to run reliably (being generous with respect to Windows reliability).
One of our customers has more than 10,000 active jobs running daily on a 4-core, 32 Gig RAM IBM i server. Consider the number of active jobs that a 256-core, 8 Terabyte RAM IBM i server might be running.
Sorry for that analogy, or comparison. I don't think that's what you were really asking about. But I do think there is a relationship.
You say, "In the PC world, one job can accommodate numerous users – dependent on the PC server’s resources, of course."
Would that "one job" you're referring to be the ASP.Net server? It wouldn't have to be. It might be a PHP server. It might be a JEE application server. Actually there are many options.
Under the IBM i framework we use, one active job might be supporting multiple concurrent users. In that case, multiple concurrent requests might be queued. The program would be responsible for managing each user's state. There would be "restore state" and "save state" operations for each request.
Our framework also supports a "launch method" where a new job is loaded and run for each user who clicks on its associated menu item. We don't limit the number of menu items that a user may have "active" at the same time. User state is automatically maintained. The active job ends when the user clicks the "Exit" link.
We also support a launch method where a specific set of users may be supported by one active job; participants in a meeting for example. When the meeting ends, it ends for all users.
We run into use cases for each type of "launch method". They each have advantages and disadvantages. It's just nice to be able to support each.
I should say something about managing complex workloads under the IBM i native environment vs. application servers such as ASP.Net, JEE Application Servers, and PHP.
In the case of the latter, you will almost always find that the only way to scale those environments and make them run reliably is to separate them into multiple physical or virtual machine instances, and front end them with load balancers, which normally requires numerous skilled people to manage.
Under IBM i, we scale by launching active jobs into subsystems, each of which may be linked to separate HTTP server instances; possibly linked to separate client organizations; keeping their workloads separate.
Overall, IBM i workload management is WAY superior to load balancing between virtual machines.
martes, diciembre 20, 2011
Brian W. Kernighan y Rob Pike sobre depuración
[Tomado de Brian W. Kernighan y Rob Pike de su libro "The Practice of Programming"]
As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places. Clicking over statements takes longer than scanning the output of judiciously-placed displays. It takes less time to decide where to put print statements than to single-step to the critical section of code, even assuming we know where that is. More important, debugging statements stay with the program; debugging sessions are transient.
jueves, noviembre 17, 2011
Críticas a OOP
(Don't Distract New Programmers with OOP)Esta nota de Hague es de marzo de este año. Por casualidad o no, ese mes otro entusiasta de la programación funcional desacredita totalmente oop. Y nada menos que en un curso introductorio de Carnegie Mellon.
[...] The shift from procedural to OO brings with it a shift from thinking about problems and solutions to thinking about architecture. That's easy to see just by comparing a procedural Python program with an object-oriented one. The latter is almost always longer, full of extra interface and indentation and annotations. The temptation is to start moving trivial bits of code into classes and adding all these little methods and anticipating methods that aren't needed yet but might be someday.
When you're trying to help someone learn how to go from a problem statement to working code, the last thing you want is to get them sidetracked by faux-engineering busywork. Some people are going to run with those scraps of OO knowledge and build crazy class hierarchies and end up not as focused on on what they should be learning. Other people are going to lose interest because there's a layer of extra nonsense that makes programming even more cumbersome.
At some point, yes, you'll need to discuss how to create objects in Python, but resist for as long as you can.
Sería muy interesante conocer un balance del curso terminado.
domingo, octubre 16, 2011
Una opinión sobre el valor de Java
"Java was not innovative at the time, and did kill many OO languages initiatives"...y a propósito del valor de Dart, Angel "Java" López ha abierto una línea de discusión e información.
I am not sure Java killed other initiatives - I feel more like they were dead on arrival, at least from a market suitability PoV.
The non-technical aspects are just as important as technical merits. It does not matter how cool a language is, if it is not going to be supported by multiple vendors/platforms, if it evolves in a way that invalidates previous investments, if it is hard to learn for the average developer, if doesn't have proper support for a wide variety of application styles/domains, if is going to be hard to hire people. Getting that right is as critical as (or even more than) technical benefits.
Java got all those right, and that is why it succeeded. I don't think it is a lot about money. Sun could have poured twice as much money into it, but if they failed to recognize the importance of those aspects, it would have been a flop, or have limited success (see Microsoft .Net). But these days I wouldn't bet against similar success being attainable by an open source foundation with a strong community, without nearly the same level of financial backing, if they aimed for building for the mainstream and the long term like Sun did with Java.
As a developer, I want my investment in learning my next language to pay off for as long and across as many domains and technical architectures as possible. That is much more important than having the perfect feature set.
Scott Klement: juego de caracteres en el AS400
Para conservar en la guía fundamental de trabajo.Things You Should Definitely Know
- It is not OK to create a text string without knowing and identifying which CCSID the data is stored in.
- It's not reasonable to expect the computer to "detect" a CCSID.
- Power Systems (and their predecessors, System i5, iSeries, and AS/400) are not "EBCDIC machines." They can run ASCII, EBCDIC, or Unicode equally well.
- The IBM i operating system (and its predecessors i5/OS and OS/400) do most of their work in EBCDIC, but they also understand both ASCII and Unicode and can run programs based on them (e.g., Java, PHP, PASE, Apache).
- IBM i has knowledge of many CCSIDs (including ASCII, EBCDIC and Unicode) built in and can easily and efficiently translate between them.
- The web is not based on ASCII. It is based on Unicode.
Things to Think About When You Have Problems
If you tell me that you have a character encoding problem, I'll want to know the following:
- How the characters were supposed to be encoded in the original file.
- What the CCSID of the original file was.
- How the characters were supposed to be encoded in the destination file.
- What the CCSID of the destination file was.
domingo, abril 10, 2011
Lenguajes de programación y rankings
The ratings are calculated by counting hits of the most popular search engines. The search query that is used is¿Son importantes estos índices? La popularidad implica que han ocupado la atención pública, que fue analizado para su adopción, que distintas comunidades recurrieron a consultas para resolver problemas o educarse, en fin, que estuvieron en el foco de la atención de la comunidad de la industria. Pero no habla en todo caso de los consolidados, aquellos que se usan sin ruido, y que pueden ser usados también en abundancia, como sin duda sucede con COBOL, RPG y otros.
+"This search query is executed for the top 6 websites of Alexa that meet the following conditions:programming"
Based on these criteria currently Google (32%), YouTube (10%), Yahoo! (3%), Bing (3%), Wikipedia (16%), Blogger (32%) and Baidu (3%) are used as search engines. The number of hits determine the ratings of a language. The counted hits are normalized for each search engine for the first 50 languages. In other words, the first 50 languages together have a score of 100%. Let's define "hits50(SE)" as the sum of the number of hits for the first 50 languages for search engine SE and "hits(PL,SE)" as the number of hits for programming language PL for search engine SE. Possible false positives for a query are already filtered out in the definition of "hits(PL,SE)". This is done by using a manually determined confidence factor per query. A query such as "Basic programming" also returns pages that contain "Improve your basic programming skills in Java". The first 100 pages per search engine are checked for possible false positives and this is used to define the confidence factor. If this factor is 90%, then only 90% of the hits are used for "hits(PL,SE)". An overview of the confidence factor can be found in the groupings table below.
- The entry page of the site contains a search facility
- The result of querying the site contains an indication of the number of page hits
The ratings are calculated with the following formula:
((hits(PL,SE1)/hits50(SE1) + ... + hits(PL,SEn)/hits50(SEn))/nwhere n is the number of search engines used.
En el último tiempo, suele hablarse de Java como un lenguaje "corporativo", igualándolo a "legacy". Su continuidad en la primera línea en todo caso muestra que su interés no se ha amortiguado.
lunes, junio 14, 2010
La supuesta muerte del RPG
"I have been writing RPG longer than some of you reading this have been alive. One recurring theme that occurs every seven or eight years is the infamous "RPG is dead" theme. Still, here we are in 2010 writing new applications in RPG IV—many of which will probably be running 30 years from now." (...) At that point in time, the C language was becoming very popular in college and university and we started to hear how RPG programmers should start learning C, or they would have no future. A few years later C++ was all the rage, and we heard the same line of advice about it related to RPG III, blah, blah, blah.RPG está atado al futuro del ISeries (o AS400). Sólidamente integrado al sistema operativo, durará tanto como dure el ISeries. El RPG es capaz de sacar del ISeries lo mejor suyo. ¿Y cuánto durará éste? Por ahora, parecería que ni IBM puede matarlo...The one consistent theme that helps push people to another programming language or application architecture is interface. When RPG III supported the 5250 devices better than anything else, people moved to it. C and C++ didn't really bring anything new to the midrange user interface table except an antiquated teletype output capability. So unless you were writing system-level code, midrange programmers ignored C and C++. Today, I use C for low-level routines or when RPG IV can't handle it. It is rare that I can't do something in RPG IV, but it's good to know that I can "drop into" C, or better yet, C++ when I need to.
Java was also largely ignored by the vast majority of midrange programmers. An infamous "vocal few" did evangelize Java to i shops, but it really doesn't provide any new interface capabilities beyond what could already be done with native RPG and DDS or the growing list of OS/400 APIs. So while Java adoption has found its way into a relatively large percentage of midrange shops, and many of those shops have at least one Java programmer, in many cases if a shop has moved entirely to Java, it subsequently moved off this operating system platform and onto lower-cost Intel/Linux or even WinTel solutions.
One cool thing I enjoy using Java for is "Internet CL." I use Java like CL when web or Internet work needs to be done, such as the SendMail application or the POI interface. Again, interface is key to the success of the implementation. In these two situations Java does something we can't easily do with RPG IV and traditional APIs. So Java should be used. Another use is cross-platform support. Perhaps even better than C, Java brags about being cross-platform independent, and largely it is. So if you have one of those third-party code generators, query tools, or report writers that generate Java (such as the hugely popular mPower from mrc), you're one step ahead of creating a catalog of platform-independent solutions.
Claramente, el problema no está en los lenguajes: para el RPG mismo, existen distintas variantes de generadores de código que intermedian la relación con el código. La gran variedad de lenguajes que proliferan aceleran la presencia de otro nivel de herramientas, capaces de superar la diversidad, y de articular lo mejor de cada uno de ellos: los que permiten el desarrollo basado en modelos, plantillas, metadeclaraciones, según el sabor de cada uno. Lejos está la época en que una aplicación podía basarse en un sólo lenguaje, en un solo hardware, y en una sola empresa. Para la etapa presente de la tecnología, el punto de vista debe estar un escalón por encima de cada lenguaje.
domingo, mayo 09, 2010
Vislumbrando el futuro de Java
Java technology is almost 20 years old, and clearly on the cusp of a new era in its evolution. Oracle's stewardship has an important role in shaping the future of Java technology, but so do the will and creativity of the Java development and open source communities.
The Java Community Process has emerged as a topic of real concern with many developers wondering whether — and exactly how — Oracle will keep its promise to both maintain and revitalize the JCP. Many expect the model of free and open source software to change under Oracle — whether subtly or dramatically — and those changes will impact how Java developers relate to the technology and their own contributions to it.
As Java technology enters its maturity, the culture of Java programming is also maturing. The drive for innovation isn't gone, but it's balanced by a growing recognition — both in the programming trenches and among CTOs and business managers — that code must be written with maintainability in mind.
Another force shaping the future of the Java platform is industry making new demands on technology while remaining, in some ways, mired in outdated thinking and ways of doing things. That must change for the Java platform to evolve and keep pace with industry needs.
If there's one message from this roundtable, it's that the future of Java technology is exciting — and also challenging. For Java developers who are able to excel in the space where rapidly evolving technology (such as cloud and mobile computing) meets a specific industry (such as health care and finance), the future looks bright and very busy.
lunes, abril 26, 2010
Algo más sobre Open Access en RPG (y el i 7.1)
Sin embargo, Scott mantiene sus reservas sobre el alcance de Open Access, cuestionando su verdadero nivel de cambio, al no modificar esencialmente la arquitectura:Rational Open Access: RPG Edition
The biggest RPG feature of 7.1 is RPG Open Access. Open Access (previously referred to as "Open I/O" in early discussions) makes it possible for programmers to write "handlers" that take the place of file I/O when you use RPG's native file opcodes.
The way George Farr explained it, under the covers, anytime you read or write from a file, RPG actually calls a routine in the OS to handle that request. For example, if you CHAIN to a record in a PF, RPG calls a routine in the database manager that retrieves a record by key. Similarly, when you use EXFMT to display a screen, it calls a routine in the display file management portion of the OS. So while we tend to think of these operations as "reading a file," the RPG runtime is really just calling a routine.
What IBM has done is open those routines up to you. You can now have it call a routine of your choosing rather than one provided by the OS. That way, you have full control over what happens when the program tries to read a file. Will it actually read a file? Or will your code simply calculate the value returned for the fields in the record? It's up to you.
People are excited about this new tool because it makes it possible for existing RPG code to use opcodes like EXFMT, READ, WRITE, etc., against a display file—but they can provide the routines that handle the display I/O. So the routine might decide to display a web page instead of a display file. Or it might decide to communicate with a Visual C++ program running on Windows, and that Visual C++ program might bring up a GUI window.
Third-party vendors are already providing prewritten handlers that RPG Open Access can call. So if you want your RPG programs to output to the web instead of outputting to a 5250 terminal, you can buy a "web" handler from a vendor, pop it in, and your program now goes to the web!
If, in the future, you want your output device to be an iPhone or iPad or Droid, it's just a matter of buying a new handler. The only change required to your RPG program is the F-spec, where you'll need to code the HANDLER keyword to tell it where to call the handler routine.
Unfortunately, I don't really have the space to go in-depth about RPG Open Access. That's something that could easily fill an article by itself. Or several articles! But if you'd like to see a more in-depth technical description, I suggest that you check out the technical documentation on the RPG Cafe.
RPG Open Access is not included with the RPG compiler, however. Instead, you have to purchase it separately from IBM. So, unless you plan to write your own handlers, you're going to need approval for two different costs: Open Access itself, plus whatever the vendor is charging for their handler.
On the plus side, it's available for both 6.1 and 7.1, so you don't even have to wait till 7.1 before you can try it out.
My opinion is that Open Access is overhyped. It has been represented as the greatest thing ever and the salvation of the RPG language, and in my opinion that's blown way out of proportion. All it does is enable a new way of calling subprocedures in a service program. Instead of calling them directly, you do file opcodes, and the file opcodes call the procedures.
No obstante, la idea me resulta más que interesante. Poner fuera el destinatario/orígen de una lectura/escritura, abre posibilidades. Es cierto que esto puede ser especialmente útil para terceros proveedores, pero justamente, es probable, desde mi punto de vista, que sea posible sacarle provecho a través de Plex, con la misma licencia, y código basado en patrones.Plus, the existing SPECIAL file support, although limited, never got a lot of adoption in the RPG community. So why come out with new tool that's almost identical to a tool that's hardly used? Is there really that much demand for it?
Furthermore, from the RPG program's perspective, it's still reading/writing a display file. Even though you may have another device on the other end, RPG doesn't know that, and so it can't take advantage of it. It can't behave like a proper web application, because it's trying to control the flow and act in a stateful manner. It can't behave like a proper GUI program, because it can't take action based on mouse events or what keystrokes a user typed into which custom controls. All it knows is how to read/write data to a display file. And we basically already had the same thing with screen scrapers, didn't we? I realize that Open Access is intercepting the program logic at a different level than a screen scraper would—but other than that, isn't it still doing the same thing? Transforming a DDS-defined 5250 screen into a GUI screen, while tricking the RPG program into thinking it's still 5250?
Más allá de los apuntes sobre Open Access, Scott resume otras novedades, tanto sobre RPG como sobre herramientas de desarrollo, licencias, almacenamiento. Para la consternación de muchos desarrolladores, el entorno de desarrollo basado en PDM, SEU, SDA, RLU, DFU, se acerca cada vez más a su fin. No quedará otro remedio que acelerar el uso de las nuevas IDEs...
martes, diciembre 08, 2009
Johan den Haan acerca de las virtudes de desarrollo basado en modelos (MDD)
Las quince razones de Johan, simplemente enumeradas:
1. MDD es más rápido
2. MDD ofrece un mejor costo (cost-effectiveness)
3. MDD conduce a una mayor calidad
4. MDD es menos propenso a errores
5. MDD conduce a validaciones más claras
6. MDD produce softwaqre menos afectado por cambios de personal
7. MDD potencia los expertos de un dominio
8. MDD permite a los programadores avanzados a enfocarse en los problemas más árduos
9. MDD tiende un puente entre el enfoque de negocios y el tecnológico
10. MDD permite que el software sea menos sensible a los cambios de requerimientos
11. MDD permite que el software sea menos sensible a los cambios de tecnología
12. MDD realmente fuerza el cumplimento de una arquitectura
13. MDD captura conocimiento del dominio
14. MDD produce documentación actualizada del modelo
15. MDD permite enfocarse en problemas de negocios en lugar de hacerlo en la tecnología
Adhiero cien por cien a ellas. Remito a su artículo para su explicación ampliada; y en unos días, volveremos y daremos una vuelta de tuerca a partir de las críticas comentadas.
sábado, noviembre 28, 2009
Plex-XML
domingo, noviembre 22, 2009
Criticas a UML
El experimento no deja muy bien parado a UML, que da diferencias a favor no muy grandes, a condición de excluír los tiempos de actualización de los diagramas. El equipo programando en Java logra mantenerse bastante cerca de los tiempos del equipo que trabaja con UML.
Estos son los aspectos que destaca Steven, comprometido con Metaedit, una de las herramientas orientadas a Domain Specific Languages mas consolidadas en el mercado, que considera revalidada su afirmación sobre el uso de UML: "empirical research shows that using UML does not improve software development productivity".
Las observaciones de Steven sobre la validez del experimento son atinadas:
Queda por ver cuánto influyó en el resultado la elección de la herramienta usada (Borland Together for Eclipse), y si otro modelador hubiera mejorado los números. Sin embargo resulta notable encontrar tanta proximidad entre uno y otro equipo. Sigue pareciendo que hacer pasar todo el desarrollo del modelo por los tipos de diagramas hoy existentes, es insuficiente. Esta es una discusión reiterada en The Model Driven Software Network, tanto en conversaciones anteriores (1, 2, 3), como en la misma que se abriera sobre este experimento.One bad thing about the article is that it tries to obfuscate this clear result by subtracting the time spent on updating the models: the whole times are there, but the abstract, intro and conclusions concentrate on the doctored numbers, trying to show that UML is no slower. Worse, the authors try to give the impression that the results without UML contained more errors -- although they clearly state that they measured the time to a correct submission. They claim a "54% increase in functional correctness", which sounded impressive. However, alarm bells started ringing when I saw the actual data even shows a 100% increase in correctness for one task. That would mean all the UML solutions were totally correct, and all the non-UML solutions were totally wrong, wouldn't it? But not in their world: what it actually meant was that out of 10 non-UML developers, all their submissions were correct apart from one mistake made by one developer in an early submission, but which he later corrected. Since none of the UML developers made a mistake in their initial submissions of that particular task, they calculated a 100% difference, and try to claim that as a 100% improvement in correctness -- ludicrous!
To calculate correctness they should really have had a number of things that had to be correct, e.g. 20 function points. Calculated like that, the value for 1 mistake would drop by a factor of 20, down from 100% to just 5% for that developer, and 0.5% over all non-UML developers. I'm pretty sure that calculated like that there would be no statistically significant difference left. Even if there was, times were measured until all mistakes were corrected, so all it would mean is that the non-UML developers were more likely to submit a code change for testing before it was completely correct. Quite possibly the extra 15% of time spent on updating the models gave the developer time to notice a mistake, perhaps when updating that part of the model, and so he went straight back to making a fix rather than first submitting his code for testing. In any case, to reach the same eventual level of quality took 15% longer with UML than without: if you have a quality standard to meet, using UML won't make you get there any more certainly, it will just slow you down.
Por mi parte, quisiera agregar a las observaciones de Steven una más:
El experimento se propone actuar sobre un modelo "en movimiento", para evitar crear un caso de condiciones ideales, en las que, arrancando de cero, se contruye una solución limpia. Sin embargo, al partir de un desarrollo prolijo, estandarizado, bien documentado, está creando un ambiente de laboratorio. Nunca la comparación entre un desarrollo basado en un modelo y un desarrollo basado en código directo (digamos 3GL) será así: en la medida que un desarrollo basado en modelos y otro equivalente basado en código evolucionen, la oscuridad del diseño crecerá, y probablemente lo hará en forma exponencial, siendo mayor el diferencial cuanto más tiempo y actores hayan pasado. Si trabajamos con un diseño de seis meses de antiguedad, las diferencias en opacidad serán no muy grandes; pero si la aplicación tiene dos, tres, cuatro años, y por ella han pasado dos o tres oleadas de desarrolladores, indudablemente será más productivo trabajar con un modelo que navegando y apostando porque el cambio que hagamos no estalle por otro lado.
En el estudio se omite que un trabajo basado en código fuente directo estará expuesto a distintos estilos de grupos o personas intervinientes, que puede tener callejones sin salida, parches, y aún fraudes o sabotajes. De ninguna manera, sobre una aplicación compleja, los tiempos de trabajar a través de un modelo podrán ser iguales a los tiempos que se tomarán haciéndolo sobre el código mismo. Y mucho menos si las personas acaban de ser contratadas para esa tarea, como pretende hacerlo el experimento.
Esto sin introducir alguna variable independiente, como por ejemplo, un cambio de versión en software de infraestructura o de framework que afecte a la aplicación.
Como siempre, debo aclarar que no uso UML en mi actividad diaria. Sin embargo, prefiero extender el alcance de las críticas al uso de herramientas de modelado en general. Soy conciente que Steven no se pronuncia a favor del código fuente, porque él lo ve desde el campo del desarrollo basado en modelos, pero compara UML contra DSLs. Este es otro asunto, que merece tiempo aparte. Pero creo que es necesario dejar bien claro que el concepto genérico de desarrollo basado en modelos es indudablemente superior al uso de código directo, y mayor cuanto más complejo sea el caso. De lo que se trata es de encontrar una fórmula para expresar de manera flexible y ágil la conducta dinámica de un modelo, algo que UML no parece resolver de manera satisfactoria todavía. ¿Existe solución? Sin duda que la habrá. En mi caso, por lo menos, una solución existe. Pero eso será también aparte.