A simple way to swap the ordinal number of any member of a list

 
I am working on the architecture of a very interesting application.
 
On one of the Use Cases, we need to provide to the actors of this use case  the ability to swap the ordinal number of any given member of a list of types of objects.
Let’s say that for one particular scenario of this use case, the types of objects are:
 
Servers, Applications, Business Processes, Business Areas, Regions.
For this Use Case, what matters is not the alphabetical order of these types in the list, but some other functionally significant order, arranged by the actors according to some meaning relative to the particular scenario.
 
Since we also must be able to persist this order, the ordinal number should be one property of the business entity that represents the aformentioned types of objects.
 
The way the actors want to change the order of any given item of the list is by selecting any given item of the list, and then promote it one level up, swapping places with the item on top of it, or demote it one level down, swapping places with the item below it.
One of the characteristics of the list that we must provide to the actors, is that the list should behave like a circular list, or a ring.
 
That means that the actors should be able to select the first item of the list and be able to send it either "up" one level, in which case, being a circular list or ring, it will swap places with the last item of the list, or send it "down" one level, in which case, it will swap places with the second item of the list.
What would be the simplest way that could possibly work for this order swap?
 
Let’s suppose that the name of the class for the types of objects is UniversalObjectType, and that the relevant property for the order swap is OrdinalNumber (you may guess correctly that it is read-write).
 
The class in charge of the responsibility of the realization of the use case (for the order swap), would have a routine very much like this one:
 
Code Sample 1
public void OrderSwap(UniversalObjectType univObjectTypeA, UniversalObjectType univObjectTypeB)
{
      univObjectTypeA.OrdinalNumber = univObjectTypeA.OrdinalNumber + univObjectTypeB.OrdinalNumber;
      univObjectTypeB.OrdinalNumber = univObjectTypeA.OrdinalNumber – univObjectTypeB.OrdinalNumber;
      univObjectTypeA.OrdinalNumber = univObjectTypeA.OrdinalNumber – univObjectTypeB.OrdinalNumber;
 
}
 
This deceptively simple routine makes the trick!
 
Let’s check this out with one scenario:
 
A list of six members, with univObjectTypeA currently at the top (OrdinalNumber = 0) and univObjectTypeB currently
at the bottom (OrdinalNumber = 5).
At the first line, univObjectTypeA.OrdinalNumber will be reassigned the sum of the two values: 0 + 5 = 5.
 
At the second line, univObjectTypeB.OrdinalNumber will be reassigned 5 – 5 = 0, in which case, univObjectTypeB will be promoted to the top of the list.
 
At the third line, univObjectTypeA.OrdinalNumber will be reassigned 5 – 0 = 5, in which case, will be confirmed at the bottom of the list.
 
Bear in mind that only in this particular scenario (where one of the items involved in the swap is the topmost of the list, whose ordinal number is equal to zero), is correct to assume that the third line of code is superfluous. In any other case, where none of the items to swap is the topmost of the list, the third line of code is necessary.
 
Besides, the third line of code would also be always necessary, if the ordinals of the list where to start with 1 instead of 0.
 
After the execution of these three simple lines of code, the two items of the list have effectively swapped places.
 
 

Una simple forma de cambiar el número ordinal de cualquier miembro de una lista

 
Actualmente estoy trabajando en la arquitectura de una aplicación muy interesante.
 
En uno de sus Casos de Uso, debemos proveerle a los actores del mismo la capacidad de cambiar el número ordinal de cualquier miembro de una lista de tipos de objetos.
 
Supongamos que, para un escenario en particular de este Caso de Uso, los tipos de objetos en cuestión son los siguientes:
 
Servers, Aplicaciones, Procesos de Negocios, Areas de Negocios, Regiones.
 
Para este Caso de Uso, lo que importa no es el orden alfabético de estos tipos en la lista, sino mas bien algún otro orden relevante desde el punto de vista funcional, a ser determinado por los actores de acuerdo con algún cierto significado relativo al escenario en particular.
 
Dado que, como tambien tenemos que poder persistir este orden, el número ordinal debería ser una de las propiedades de la Entidad de Negocios que representa a los tipos de objetos ya mencionados.
 
La forma en que los actores quieren poder cambiar el orden de cualquier item de la lista es mediante la selección en la lista del item en cuestión, y luego promoverlo un nivel hacia arriba, en cuyo caso intercambiará lugares con el item que esta encima de el en la lista, o democionarlo un nivel hacia abajo, en cuyo caso itercambiará lugares con el item que se encuentra abajo de el en la lista.
 
Una de las características de la lista que debemos proveer a los actores, es que la misma debería comportarse como una lista circular, o un anillo.
 
Esto significa que los actores deberían, por ejemplo, poder seleccionar el primer item de la lista, y poder enviarlo tanto un nivel "arriba", en cuyo caso, siendo una lista circular, intercambiará lugares con el último item de la lista, o enviarlo un nivel "abajo", en cuyo caso, intercambiará lugares con el segundo item de la lista.
 
Cual sería la expresión mas simple que podría funcionar para este intercambio de número ordinal?
 
Supongamos que el nombre de la clase de los tipos de objetos es UniversalObjectType, y que la propiedad relevante para esta rutina es OrdinalNumber (adivinarán correctamente que esta propiedad es Read-Write).
 
La clase a cargo de la responsabilidad de la realización del Caso de Uso (el cambio del número ordinal) tendría una rutina muy parecida a la que se muestra en Code Sample 1.
 
Esta rutina, engañosamente simple, es capaz de realizar el truco!
 
Verifiquemos que así es, mediante un escenario de ejemplo:
 
Una lista con seis miembros, con univObjectTypeA actualmente al inicio de la lista (OrdinalNumber = 0), y univObjectTypeB actualmente al final de la lista (OrdinalNumber = 5).
 
En la primer línea de la rutina, a univObjectTypeA.OrdinalNumber se le reasignará 5 – 0 = 5, en cuyo caso, será democionado al último lugar de la lista.
 
En la segunda línea, a univObjectTypeB.OrdinalNumber se le reasignará 5 – 5 = 0, en cuyo caso, será promovido al primer lugar de la lista.
 
En la tercer línea, a univObjectTypeA.OrdinalNumber se le reasignará 5 – 0 = 5, en cuyo caso, se lo confirmará como el último item de la lista.
 
Tener presente que sólo en este escenario particular (donde uno de los items a intercambiar es el primero de la lista, cuyo número ordinal es igual a cero) es válido suponer que la tercer línea de código es redudante. Para cualquier otro caso, donde ninguno de los items de la lista a intercambiar es el primero de la misma, la tercer línea de código es necesaria.
 
Por otro lado, tambien sería necesaria la tercer línea de código para todo caso, si los ordinales de lista comenzaran con el 1 en vez del 0.
 
Luego de la ejecución de estas tres simples línea de código, ambos items de la lista habrán efectivamente intercambiado sus lugares en la misma.
 
 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s