martes, 12 de julio de 2011

Generadores de código - Un programador más

¿Han pensado en este concepto? Un programador en la Argentina es un analista, un codeador, una persona que resuelve problemas. A veces incluso es organizador, anticipador, y se prepara para lo que viene. Toma decisiones y colabora junto a los demás para realizar sus tareas.

En cambio un generador de código es una máquina boba de escupir código. Es un mono que programa a una velocidad rampante. Pero no sabe ni qué está programando, ni qué está escribiendo. Él sólo escupe código. Para eso lo inventaron, y para eso está. No realizará análisis ni tomará decisiones.

Quien puede hacer eso es quien usa al generador de código como una herramienta. El decide qué debe crearse y cómo.

Ahora, todo esto me parece correcto pero quedándonos con sólo esta idea nos podríamos confundir un poco. Podríamos pensar que el código que se "escupe" puede ser redundante y sin reutilización. ¡Total, se re-hace en un segundo!. Es una de las principales premisas que veo en los generadores de código empresariales. Hacen un código desastroso, con casi ninguna herencia ni orientación a objetos, porque igualmente lo podemos re-generar con los cambios en un segundo. El tema es que nos encontramos con los siguientes problemas con el código una vez generado.

La reutilización no se tuvo en cuenta, por ende se hace difícil utilizarlo el código hecho en un futuro.

Por ejemplo, generamos automáticamente las clases de acceso a datos. Lo que no se tuvo en cuenta es que dicho código utilice algún framework ORM propietario o de terceros, cosa de que el código sea más reutilizable y legible.

Por ejemplo, quizás estas clases de acceso a datos se generan con SQL Server en la cabeza, y cuando necesitamos pasar a Oracle tenemos que ir a re-generar el código (en el mejor de los casos!). Y cuando re-generamos nos encontramos con que:

  1. El comportamiento del código es diferente
  2. Interfaces desactualizadas o incompatibles.
  3. Hay métodos que recibían objetos de un tipo y ahora reciben de otro
  4. La nomenclatura de procedures y parámetros que está utilizando es diferente al implementado
  5. Los scripts SQL generados tienen errores
  6. Los templates de generación de código nunca se probaron

O sea que podemos caer en una situación incómoda. En realidad nosotros deberíamos tener una clase de LÓGICA de acceso a datos. De ahí viene el nombre "DAL". Data access LOGIC. Pongo LÓGICA en caps porque para mí eso significa que debe manejar "cómo" se deben acceder los datos y de qué forma se traducen a entidades/objetos del sistema. Para mí NO debe tener detalles de bajo "qué" están dichos datos.

Utilicemos clases de acceso a datos inteligentes, como si las hubiera programado un programador decente. Que utilicen un framework que nos permita cambiar la base de datos simplemente cambiando la configuración, no re-generando todo el código.

Terminamos con un archivo donde "tocar" y un archivo donde "no tocar"

Esta también es típica. Para una clase nos genera dos archivos de partial class, donde uno tenemos un cartel gigante que dice "NO MODIFICAR". Esto para mí es un conocidísimo anti patrón. Tener 2 archivos para una clase es un tema. Tener 100 archivos para 50 clases es otra.

Otra cosa que he visto a veces es que todo el código generado lo pegan en un sólo archivo universal (que a veces alcanza las decenas de miles de líneas de código) y luego es un desastre regenerar algo. Esto es obviamente una respuesta poco pensada al hecho de darse cuenta que tener tantos archivos que no se pueden pisar es inútil.

Lo cierto es que nuestros generadores deberían ser inteligentes. Tomar el código que deben reemplazar y listo. No que debamos regenerar todo y pisar los fuentes, eso es medio negrada. Simple y puede ser efectivo si se controla como corresponde, pero a la larga trae problemas.

Para lograr esto tendríamos que tener metainformación sobre las clases generadas. Y qué mejor para eso que Reflection!. En .NET al menos podemos consultar cómo está compuesta una clase, y luego el generador puede decidir qué reemplazar y qué no, y ante un código que no sabe que hacer, dejarnos la decisión a nosotros.

Esto nos permitiría, además, pensar en regeneraciones parciales de clases. El código que debe crearse debe tener la menor cantidad de correspondencias privadas internas entre métodos y propiedades posibles, sin sacrificar la cohesión y la reutilización.

De repente algunos eslabones de la cadena de archivos generados no sirve

A veces, por la arquitectura seleccionada, algunos eslabones no sirven para nuestro sistemas. Imaginemos, por ejemplo, que nuestro generador nos crea unos webservices que luego llama desde la UI, por decir una boludez. Quizás nuestro sistema posee una arquitectura donde la UI se comunica directamente con la capa de negocio. Por ende, estaríamos teniendo que realizar un trabajo manual de adaptación sólamente para nuestro sistema.

Lo que deberíamos tener es una configuración de cómo se interconectan las capas generadas. Cada capa tiene sus propios templates que generan sus archivos, pero sería bueno que nuestro generador reconozca la configuración que nosotros deseamos, y nos genere las dependencias correctamente con nuestra arquitectura. Entonces puedo generar que la UI se enlace a WebServices, o que la UI se enlace a Negocio, o que la UI se enlace a la base de datos (horrible) según me convenga a mí. Y eso sólo con unas configuraciones. Es más fácil de armar de lo que parece.

Tomamos decisiones de arquitectura basándonos en nuestras herramientas y no en nuestros conocimientos

Este punto es importantísimos. Supongamos que creamos un generador de código que nos crea las siguientes capas:

  • Capa de Acceso a datos
  • Capa de Entidades
  • Objetos Estáticos tipo Facade que se comunican con la base de datos (una especie de Negocio pero con una implementación fea)
  • UI en archivos ASPX que se comunican sólamente con los objetos estáticos.

Cuando nuestros profesionales analicen y decidan "che, tengo una arquitectura mucho mejor", no la podrán aplicar hasta re-escribir los templates (en el mejor de los casos) o el generador de código. Los proyectos iniciarán y habrá una desmotivación por no poder aplicar una mejor arquitectura solucione los problemas de esta arquitectura auto-generada, simplemente por temas de tiempo (Que probablemente perdamos mas adelante).

Y así podríamos seguir mencionando problemas de los generadores de código actuales. Lo mejor sería tener un generador compuesto por pequeñas partes que nosotros podamos ir mejorando de forma independiente, manteniendo ciclos de desarrollo cortos, como para poder irlo mejorando seguido, y no tener que esperar a tener 3 meses con poco trabajo, que generalmente nunca ocurre. Todos los software se actualizan constantemente. Pero los de uso interno rara vez. ¿No habrá un problema ahí?

Los dejo con esta idea.

jueves, 7 de julio de 2011

Piqueteros y fanáticos de Harry Potter cortan todas las Autopistas de Capital

Se encuentra colapsado el sistema vial debido a manifestantes que exclaman por mayores salarios y la continuación de la saga de Harry Potter. La presidenta ha salido con pancartas a la calle a protestar por lo sucedido.

martes, 8 de febrero de 2011

.NET: Getting current method name or a method in the stack frame

I would love to go into the details of what is and how the StackFrame object works. However, I'm a little short on time right now, but I'm pretty sure I will make a post about it in the future.

For now, let's focus on how to get a very common functionality, but that isn't applied much yet. First, let's see what we can get and how. Next, I will give you some ideas on where to apply it.

You can 2 things to get the current method name. Using reflection:

string MethodName = System.Reflection.MethodBase.GetCurrentMethod().Name;

Or using the StackFrame:
string MethodName = new StackFrame(0).GetMethod().Name;
Cool, now we get the current method name. Now what if we wanted the previous method? Perhaps my method is called from various places and I do not wish to have their name as a parameter.
We can use StackFrame for this:
string MethodName = new StackFrame(1).GetMethod().Name
So, what can we use this for? Let's see some ideas:
  • Now our loggers can keep track of the method that's logging the information.
  • Gettng the methods (not the name) can help you retrieve the parameters it has received. We will see this in a future post. This information can be excellent when your application is deployed and you are getting an error that you can not reproduce.
  • In a certain way, you could limit the methods that can call your method. This seems weird at first, but perhaps some security folks can use this to their advantage.
  • Remove all those hardcoded strings!! Or constants at least :)

Being busy!

Hey! I am planning to create some Architecture post about Microsoft SharePoint and it's diabolic SPListItem object, an object that everyone has to deal with.

I also hope to be able to include some UML screenshots =).

Also, I want to create a post about how to start working as a freelancer. What you need, what software you should have, where to seek clients and how to deal with them :).

Regards,
Christian

jueves, 3 de febrero de 2011

SQL Server: Temporary tables

In stored procedures you can create temporary tables, save data into it and use it like some sort of temporary repository, or anything you can think of. This is specially useful in complicated stored procedures. Remember, not every single client you have will prefer having the data logic in a data access layer in your application, some will prefer implementing that logic in the database itself. Heck, some even will want their business logic there.

This type of tool can come in very handy. You can just create a table like:

CREATE TABLE #Tmp (
ID int,
Name varchar(30) )

Note the # at the begining of it's name. This table will last during the whole sql server session, and will get deleted inmediately after that. However, if you can to delete it yourself with a DROP TABLE instruction, you can just do that. No error will be thrown.

PD: I promise one day I'll format the code on the blog a little better. It has a very rustic formatting right now.

SQL Server: Inserted and Deleted special tables in stored procedures

This is something I've never used before, because I didn't use triggers at all. Check this quote from MSDN, full link at the bottom of the post.

Two special tables are used in trigger statements: the deleted table and the inserted table. Microsoft® SQL Server™ 2000 automatically creates and manages these tables. You can use these temporary, memory-resident tables to test the effects of certain data modifications and to set conditions for trigger actions; however, you cannot alter the data in the tables directly.
The inserted and deleted tables are used primarily in triggers to:
  • Extend referential integrity between tables.
  • Insert or update data in base tables underlying a view
  • Check for errors and take action based on the error.
  • Find the difference between the state of a table before and after a data modification and take action(s) based on that difference.
The deleted table stores copies of the affected rows during DELETE and UPDATE statements. During the execution of a DELETE or UPDATE statement, rows are deleted from the trigger table and transferred to the deleted table. Thedeleted table and the trigger table ordinarily have no rows in common.
The inserted table stores copies of the affected rows during INSERT and UPDATE statements. During an insert or update transaction, new rows are added simultaneously to both the inserted table and the trigger table. The rows in the inserted table are copies of the new rows in the trigger table.
An update transaction is similar to a delete operation followed by an insert operation; the old rows are copied to thedeleted table first, and then the new rows are copied to the trigger table and to the inserted table.
When you set trigger conditions, use the inserted and deleted tables appropriately for the action that fired the trigger. Although referencing the deleted table while testing an INSERT, or the inserted table while testing a DELETE does not cause any errors, these trigger test tables do not contain any rows in these cases.

Source(s): MSDN

SQL Server: Update a table based on another table

When I worked in a small software factory many years ago (it was my first IT job) I always wanted to know how to do this, and couldn't find satisfactory solutions in the web. Now that I'm back to SQL Server programming, it was time to unveil this mistery. Here it goes!


UPDATE TargetTable SET
Field1 = t1.Value1,
Field2 = t2.Value2
FROM OtherTable T1
LEFT JOIN YetAnotherTable T2 ON T1.SomeID = T2.ID
WHERE T1.ID = 1


So there you have it. It is very simple and it can be very handy, specially in stored procedures where sometimes you want to make the less Select instructions possible.


You can also do the same using INSERT SELECT FROM, but that's very easy to find on the web.


Have fun refactoring!

miércoles, 2 de febrero de 2011

SQL Server: NOCOUNT

I always saw the SET NOCOUNT ON/OFF instruction in SQL Server stored procedures and triggers, but never knew exactly what it did. This quote from MSDN explains it perfectly:
Stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set.
So, apparently it diminishes some network traffic by not showing the message of number of rows affected.

Full Article here.

SQL Server: NVARCHAR versus VARCHAR

I've never used NVARCHAR until now, where the sql server coding standards demands me to use nvarchar in most cases. So I was thinking "What's the difference?". Googling around I found a satisfactory answer. Let me quote it:

SQL Server provides both datatypes to store character information. For the most part the two datatypes are identical in how you would work with them within SQL Server or from an application. The difference is that nvarchar is used to store unicode data, which is used to store multilingual data in your database tables. Other languages have an extended set of character codes that need to be saved and this datatype allows for this extension. If your database will not be storing multilingual data you should use the varchar datatype instead. The reason for this is that nvarchar takes twice as much space as varchar, this is because of the need to store the extended character codes for other languages


Source(s):
A WebLogs post

martes, 1 de febrero de 2011

.NET: Debug a Windows Service without deploy

Have you ever wanted to debug a windows service without installing it? Well, there is a very easy way to do this. I am going to show it in this post, and maybe we can discuss more "elegant" solutions in future posts.

When you create a Windows Service project, a "Program" class is created, with a Main method, which is the entrance point of your application. This methods calls ServiceBase.Run, passing an array of service classes as arguments, so in theory you can run a number of classes at the same time under the same windows service process.

Now, this ServiceBase.Run method won't work in a debugging environment. How can we achieve this? Using code expansion!

#if (!DEBUG)
    ServiceBase[] ServicesToRun;
    ServicesToRun = new ServiceBase[] 
    { 
        new MyService() 
    };
    ServiceBase.Run(ServicesToRun);
#else
    MyService service = new MyService();
    service.Initiate();
    System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#endif

Pretty neat huh? DEBUG is a environment variable that is registered within the visual studio environment. You can create your own (we will see them in other post). So, when the DEBUG configuration is used to compile, the code is just like above. But when RELEASE is used, the compiler will check for these # constructions and only compile the code that corresponds, so there is no way the sleep line is going to be called when installed.

Initiate is a public method that you must define. Name it whatever you want, and call it from your OnStart routing within the service class, like following.

protected override void OnStart(string[] args)
{
    Initiate();
}

Have fun debugging!

New job

This is my first day in my job as a Senior Developer in a medium size software factory. After being part of a huge multinational I can tell you that I was missing the small environments, where you can do really significant stuff.

I have been checking their code for a few hours and I can already tell a lot of things that could be improved to raise the code quality level.

However, I'm going to wait a few months before proposing any ideas.

By the way, I have been doing some research on SharePoint server object model and have built a framework to use some important but complicated items, that tend to fail and throw exceptions without a really good reason. We will catch on that!

.NET: Enum values as bit flags

This should be something easy to accomplish, but it is a little trickier for those who start programming.

Sometimes we would like to use an enum as a set of flags, so we can set several "states" of the same property to a combined state of several values. Let's see an example. Imagine we have the following enum class:

public enum ExportTypes
{
   Text,
   Excel,
   CSV,
   JSon,
   XML
}

So, we have a set of types of exportations for something in our program. Now, this enum would only allow us to have a single export type. Perhaps we would like two, or three, or all of them. Should we run the program several times? Should we add a single property for each type of import and make it boolean?

A better option would be to say something like "Export text AND excel". How can we accomplish that with an enum? We just need to add the FlagsAttribute as a decorator for this enum class.

[Flags]
public enum ExportTypes
{

   None,
   Excel,
   CSV,
   JSon,
   XML,

   Text,
}

Now, we can use the bitwise operator OR to add several values of the same enum. For example, imagine the following class that receives the enum values in one of it's properties.


ExportExecution.ExportTypes = ExportTypes.Text | ExportTypes.Excel;

Now, the problem is not writing to this property, but reading from it. Let's suppose that we have a method called "Export" that has a bifurcation when the export type is Text. We just have to use the bitwise operator AND to find out if the Text value is set to the property. Check the following example.

if(this.ExportTypes & ExportTypes.Text == ExportTypes.Text) {


This would check that the Text property is contained within the values set. This is a very bad explanation, but Im saving it for later, so I could explain this first to you.

Now you know how to create and use a bit flag enum class. But, what the hell just happened? Why does it work? It is important to understand this, otherwise you may end up being a mindless programmer building a trench in a crappy job believing you can be better than that. Ok, maybe that's a small exageration.

Basically, what you have is the following values.

public enum ExportTypes
{
   None = 0
   Excel = 1
   CSV = 2
   JSon = 4
   XML = 8
   Text = 16
}

They all scale in the potency of 2, because bit enconding has 2 values. So, let's say you want Excel and JSon. That would be like 1 + 4 or 0101. You see? each enum value is a 1.

0000000 is nothing
0000001 is excel
0000010 is CSV
0000011 is excel and CSV

Now, a last hint. The first value will be ZERO so it is always TRUE. This should never be a value where you ask for it being false, since it will always be present.

viernes, 28 de enero de 2011

Tools: Convert ICO Files

Sometimes you get to find some interesting free online services. Who hasn't needed to convert an image to an ICO file? Or the other way round?

Well, I have been using the following site for that:

http://www.convertico.com/

This is not publicity. Just sharing a small tool. Some stuff about programming will soon come!

jueves, 27 de enero de 2011

We can always dream

Hello everyone. My name is Christian and I’m an IT professional in Argentina. Since my first job back in 2005 I got really interested in frameworks, design patterns and software architecture. Soon I started to study by my own how the software architect role should fit into a company, together with the technical analysts and other architecture-related positions.

Needless to say, I still continue my studies every day. Improving existent frameworks, products, design patterns, and such stuff is what really makes me an IT fanatic. Supreme quality is always one of my concerns, although we are forced to make the "correct" product before making it "correctly".

This blog is about that. Design patterns, software architecture, frameworks, coding quality and most important of all: Learning.

You are all welcome to join me in my eternal quest: The dream of software architecture.