knocte :: MonoTema
It’s all about synchronization
Mayo 31st, 2009 - [Enlace local]
It's been a while since I first blogged about iFolder. At that time it was a bit unstable and I didn't have a good experience overall with it. Unfortunately the development of new features stopped, but there were a lot of fixes to improve its stability, which made into the version 3.7. Unfortunately again, this version was not released on the open, but now Novell has rectified and iFolder is
» Leer más, comentarios, etc...
Blog de Julio César Pérez Arques
Cuando la crisis golpea una consultora IT
Mayo 30th, 2009 - [Enlace local]
Estaba cantado. La crisis ha llegado a nuestro sector. Va a quedarse y va a hacer daño. Ha tardado lo justo en que las empresas del resto de sectores ya en crisis se han recortado su presupuesto en proyectos IT, tanto nuevos como de mantenimiento. El resultado (previsible) es que el modelo de negocio de las grandes consultoras IT no se sostiene y no se sabe adaptar a la nueva situación.
Son ya muchos años explotando un modelo de servicios desde un punto de vista basado unicamente en los números a corto plazo. Sin importar mucho más. Tecnología, conocimiento, proyectos, trabajadores o clientes. Son mentes financieras las que mueven los hilos al más alto nivel. Para ellas, el negocio IT no es muy diferente de cualquier otro, como podría ser el de las máquinas expendedoras.
Modelo de negocio Máquina expendedora
Existe una necesidad: el código. Y las consultoras hacen negocio con máquinas expendedoras de código. El código es un bien caro y se genera directamente dentro de las máquinas. Sin necesidad de comprar ninguna materia prima.Que un cliente necesita código, pues negocias cúantas máquinas de cada tipo le pones, por cúanto tiempo y, ala, a facturar.
Las máquinas no tienen coste inicial, sólo de mantenimiento (salario) pero tampoco es que sea mucho. Como cualquier coste, se intenta reducir al máximo. No tiene mucha más preocupación. La prueba está en que existe una generalizada inversión de salario, donde no siempre a una máquina que aporta mayor valor le corresponde un mayor coste (salario).
Las instalaciones tampoco es que sean excesivamente costosas (luz, agua, ordenadores, internet,...) o amplias, ni necesiten estar estrategicamente situadas. Además, con suerte, al cliente le da por tener las máquinas en sus propias instalaciones, por lo que es un gasto menos.
En realidad no hace falta un modelo de negocio muy sofisticado. Ya es un negocio por si solo!
Últimamente estaban teniendo el doble problema de que se iban demasiadas máquinas y que además habia escasez de nuevas máquinas. La solución (muy finaciera) ha sido (1) adquirir máquinas que no son expendedoras de código pero pueden pasar por ellas (o al menos se lo parece), (2) importar o usar máquinas de otros paises y (3) subcontratar a otras consultoras más pequeñas y baratas. En realidad nada grave que requiera cambiar el modelo.
El golpe
El modelo era un éxito. Los records de facturación se han ido sucediendo año tras año. Hasta ahora. Al caer la economía de los grandes clientes de código, las consultoras se encuentran con excedentes de máquinas, los beneficios han caido y los objetivos se alejan.Las primeras medidas
Una vez más, se toman medidas desde un punto de vista financiero. Dejar de contar con ese excedente de máquinas no es caro, mientras no sean muchas. Además las máquinas, de siempre, ni se quejan en exceso ni hacen mucho ruido. Así que no llevamos ni medio año de efecto crisis y ya asoman los primeros EREs. Y los que no se han dado ya es por no perder cotización en bolsa.Otras medidas a tomar, igual de rápidas que de injustas, son:
- Congelación de sueldos. El año pasado batiste record de facturación y se te paga congelándote el sueldo...
- Invitaciones al personal en available para tomarse unas vacaciones sin sueldo aunque cotizando.
- Reducción de la jornada laboral.
- Reducir el número de días de vacaciones. Claro, todo el mundo sabe que aumentando en número de horas trabajadas, aumentas la productividad. Ésto último era puro sarcasmo.
Alternativas
Se echa en falta un poco de imaginación y de conocimiento del sector. ¿Por qué no hacer?- Formación. Se puede impartir y recibir cursos en vivo u online. Personal más preparado sí es igual a mayor productividad.
- Investigación. Se puede investigar y evaluar nuevas tecnologías, herramientas y metodologías que permitan un verdadero aumento de la productividad.
- Desarrollo de productos. Para posteriormente intentar su venta. Vender productos no genera un beneficio tan inmediato como vender servicios porque primero hay que desarrollar el producto, pero da dinero y prestigio.
- Desarrollo de aplicaciones internas. Ya se sabe que en casa de herrero, cuchillo de palo, así que seguro que las aplicaciones internas son más que mejorables. Mejores aplicaciones intenas también mejora la productividad.
- Incrementar la dotación en los proyectos activos. Ésto supone perder dinero o ganar menos en estos proyectos, pero seguro que incrementaremos la satisfacción del cliente y nuestras opciones para obtener nuevos proyectos con él.
- Dar soporte a compañeros de otros equipos. Pocas veces eres el primero en resolver un problema, en vez de preguntar a Google o probar por probar, por qué no preguntar a un compañero de otro equipo.
- ¿Colaborar en proyectos open-source de los que tu empresa se lleva lucrando años? Ja, que me da la risa...
Futuro
La vida son ciclos. Al final la crisis se irá. Algunos habrán caido, otros se habrán mantenido a flote y los más preparados habrán crecido. Pero, ¿habremos aprendido algo?» Leer más, comentarios, etc...
HardBit
Nuevo inicio
Mayo 30th, 2009 - [Enlace local]
Bien, tiene rato que no posteo y esta vez no sera tecnico, solo para mencionar que dejo mi empleo en Eviciti y me inicio en una nueva aventura (jojojo) en emlink, confio en que me ira bien y por supuesto seguire manteniendo este blog.
» Leer más, comentarios, etc...
PROGRAMANDO EN .NET
Truco rápido: Histórico de cambios en una tabla usando un trigger
Mayo 29th, 2009 - [Enlace local]
No me voy a enrollar explicando que es un trigger ni para que sirve, tenéis información de sobra en este link: CREATE TRIGGER (Transact-SQL) Lo que voy a explicar aquí es como usar un trigger para que nos guarde en una tabla de históricos los cambios (INSERT y UPDATE) que se producen en una tabla. Para ello supongamos que tenemos una tabla con un identificador (campo Id) y un nombre (campo nombre
» Leer más, comentarios, etc...
PROGRAMANDO EN .NET
Cambio de aires
Mayo 27th, 2009 - [Enlace local]
Dicen que estamos en crisis y que es mal momento para encontrar trabajo ... igual es que yo tengo suerte porque hace un par de semanas que me he cambiado de empresa :DHe dejado un cliente final (en el que se vivía muy bien) para volver al fascinante mundo de la consultoría, por ahora en un muy buen proyecto (del que os aburriréis de oir hablar) y con un grupo majo de personas para currar :)A los
» Leer más, comentarios, etc...
Mal Código
Cosas que hacer en la tesina
Mayo 19th, 2009 - [Enlace local]
Este último mes lo que más me ronda por la cabeza (a parte de pillarme un ordenador nuevo para volverme a pasar el Fallout 3 en condiciones) es terminar de escribir la tesina final del máster que estoy haciendo. El trabajo que me había planteado hacer esta terminado (y pocas ganas tengo de hacer más sobre el tema), ahora solo me queda poner por escrito en unas 40~50 páginas que es lo que he hecho
» Leer más, comentarios, etc...
DGG
Las oficinas de Fog Creek
Mayo 15th, 2009 - [Enlace local]
¿Cuándo podremos ver en España unas oficinas como las de Joel Spolsky? Si las comparo con la mía me deprimo, (y eso que he según lo que hay por aquí no me puedo quejar).
Resumiendo, todos los puestos en esta oficina tienen las siguientes características:
- Todas las oficinas son privadas, para que te concentres en el código y no interrumpan todo el tiempo. Aquí en España lo más normal es que haya gente hasta en los pasillos con mesas supletorias. Además, todas tienen ventanas para que te relajes con las buenas vistas de Nueva York.
- Mesa motorizada ajustable en altura, para trabajar de pie si me da la gana. Aquí te tienes que conformar con lo justo para el portátil.
- Monitores de 30″, incluso algunos puestos tienen hasta 2 monitores. Y yo pasándome 8 horas con un portátil de 15,4″.
- Comedor gratuito, bonito y espacioso para comer todo el mundo a la vez. Se acabó eso de llevar tuppers.
- Coffee bar gratuíto. Fruta en todos los puestos, snacks, una nevera llena de bebidas. Mirar las fotos y comparad.
- Biblioteca
- Varias salas de reuniones de diferentes tamaños. Allí no se pelean por resevar la sala.
Bueno, sólo quería demostrar que son diferentes las cosas allí y aquí, y espero que poco a poco aquí vayamos cogiendo todo lo bueno de allá y no al revés.
Para más información: el blog de Joel Spolsky y el álbum de Picasa con las fotos de las oficinas.
Posted in Gestión Tagged: management
» Leer más, comentarios, etc...
Thefull
DNSMasq. Servidor de cache DNS.
Mayo 15th, 2009 - [Enlace local]
Una de las cosas que más me gustan de GNU/Linux son las infinitas opciones que existen para un montón de pequeñas cosas, como por ejemplo, usar un servidor de cache para DNS y DHCP.
» Leer más, comentarios, etc...
Blog de Julio César Pérez Arques
Hacer accesible un método Java en tiempo de ejecución
Mayo 14th, 2009 - [Enlace local]
No es habitual. Puede que incluso sea síntoma de un mal diseño OO. Pero en ocasiones nos puede venir muy bien ser capaces de hacer accesible un método en tiempo de ejecución. Por ejemplo, para hacer pruebas de un método privado.
El truco está en usar Reflection. Reflection es un API Java que forma parte del JDK (paquete java.lang.reflect) y que permite acceder y manipular la meta-información de las clases y objetos de tu código Java en tiempo de ejecución. No es algo que se use todos los días (a no ser que programes ides, debuggers o frameworks), pero conviene saber que existe y conocer sus capacidades, por si acaso...
Pero vayamos al grano. El código es muy sencillo. A partir de una instancia, (1) obtenemos su objeto Class, (2) obtenemos el objeto Method que representa el método en cuestión, (3) modificamos su accesibilidad y (4) finalmente lo ejecutamos pasándole los argumentos necesarios y guardamos su salida si tiene. Un ejemplo de un método sayHello con un parámetro String y un return String sería éste:
Method metodo = instancia.getClass().getDeclaredMethod("sayHello", new Class[]{String.class});
metodo.setAccessible(true);
String salida = (String)metodo.invoke(instancia, new Object[]{"argumento1"}));
¿Y si fuera un constructor? Practicamente igual, pero usando esta vez el objeto Constructor y teniendo en cuanta que ahora no tenemos una instancia. Un ejemplo con un constructor sin parámetros sería éste:
Constructor constructor = NombreClase.class.getDeclaredConstructor(new Class[0]);
constructor.setAccessible(true);
NombreClase instancia = (NombreClase)constructor.newInstance();
Y esto es todo. Rápido y fácil. Ahora no lo uséis mal...
» Leer más, comentarios, etc...
Developing my life » desarrollo
Subir archivos usando un widget P4A_Field
Mayo 13th, 2009 - [Enlace local]
En el proyecto que estoy trabajando actualmente usando P4A, tengo una pantalla maestro-detalle en el cual tengo que registrar entre otros datos n-archivos. Si los archivos se registrasen directamente en el maestro entonces no hay problema porque el object P4A_Data_Field que esta enlazado al P4A_DB_Source que a su vez hereda de P4A_Data_Source y este ultimo object es el que maneja los uploads de archivos que se ingresan a través de los P4A_Data_Field tipo “file” mediante su método saveUploads().
Pero como repito todo esto perfecto si el archivo esta directamente en el maestro, pero si esta en el detalle donde no usas P4A_Data_Field, sino widgets P4A_Field, entonces te jodiste, porque solo lo deja en “uploads/tmp”, pero no lo sube al “uploads” o al dir que le pusiste en el setUploadSubpath() . Por qué no lo implementaron para un widget simple y silvestre?, ni idea. Pero no te preocupes, como dijo Ernesto:
Bueno hackear P4A es una tarea complicada pero no imposible.
Asi es vamos a hackear P4A, si no esta implementado porque esperar a que lo hagan, si puedes hacerlo tu, ya tenemos una pista el metodo saveUploads() del P4A_Data_Source ubicado en “ruta_instalacion_p4a/p4a/objects/data_source.php” es el que hace la magia de los uploads, entonces lo que debemos hacer es guiarnos de el y realizar las modificaciones para que funcione para un widget P4A_Field simple y silvestre. Entonces llamaremos al metodo “saveUpload” (que original no?
) y lo implementamos/agregamos en el archivo “ruta_instalacion_p4a/p4a/objects/widgets/field.php”, quedando asi:
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 | /** * Moves uploaded file from P4A_UPLOADS_TMP_DIR to P4A_UPLOADS_DIR * @throws P4A_Exception */ public function saveUpload() { $field_type = $this->getType(); if ($field_type=='file') { $new_value = $this->getNewValue(); $old_value = $this->getValue(); $target_dir = P4A_UPLOADS_DIR . '/' . $this->getUploadSubpath(); if (!is_dir($target_dir)) { if (!P4A_Mkdir_Recursive($target_dir)) { throw new P4A_Exception("Cannot create directory \"$target_dir\"", P4A_FILESYSTEM_ERROR); } } $a_new_value = explode(',', substr($new_value, 1, -1 )); $a_old_value = explode(',', substr($old_value, 1, -1 )); if ($old_value === null) { if ($new_value !== null) { $a_new_value[0] = P4A_Get_Unique_File_Name($a_new_value[0], $target_dir); $new_path = $target_dir . '/' . $a_new_value[0]; $old_path = P4A_UPLOADS_DIR . '/' . $a_new_value[1]; if (!rename($old_path, $new_path)) { throw new P4A_Exception("Cannot rename file \"$old_path\" to \"$new_path\"", P4A_FILESYSTEM_ERROR); } $a_new_value[1] = P4A_Strip_Double_Slashes(str_replace(P4A_UPLOADS_DIR , '', $new_path)); $this->setNewValue('{' . join($a_new_value, ',') . '}'); } else { $this->setNewValue(null); } } else { if ($new_value === null) { $path = $target_dir . '/' . $a_old_value[0]; if (!@unlink($path) and @file_exists($path)) { throw new P4A_Exception("Cannot delete file \"$path\"", P4A_FILESYSTEM_ERROR); } $this->setNewValue(null); } elseif ($new_value!=$old_value) { $path = $target_dir . '/' . $a_old_value[0]; if (!@unlink($path) and @file_exists($path)) { throw new P4A_Exception("Cannot delete file \"$path\"", P4A_FILESYSTEM_ERROR); } $a_new_value[0] = P4A_Get_Unique_File_Name($a_new_value[0], $target_dir); $new_path = $target_dir . '/' . $a_new_value[0]; $old_path = P4A_UPLOADS_DIR . '/' . $a_new_value[1]; if (!@rename($old_path, $new_path)) { throw new P4A_Exception("Cannot rename file \"$old_path\" to \"$new_path\"", P4A_FILESYSTEM_ERROR); } $a_new_value[1] = str_replace(P4A_UPLOADS_DIR , '', $new_path); $this->setNewValue('{' . join($a_new_value, ',') . '}'); } } } } |
Listo ya tenemos nuestro metodo para subir archivos mediante un widget P4A_Field, ahora como lo usamos, un ejemplito:
1 2 3 4 | $this->build("p4a_field","txt_miarchivo") ->setType("file") ->setUploadSubpath(directorio_especial) // esto siempre y cuando lo quieras subir dentro de un directorio especial dentro del uploads, sino se subira por defecto en el directorio uploads. ->setLabel("Archivo: "); |
Listo ya tenemos nuestro widget creado claro ahi tienes que agregarlo a tu pantalla/form, pero eso ya sabes como hacerlo
. Ahora para usar el metodo implementado por nosotros solo invocamos al saveUpload(), asi:
1 2 3 4 5 6 7 | public function guardaData() { // procesos que quieras antes $this->txt_miarchivo->saveUpload(); // procesos que quieras despues } |
Y ya esta!
, espero les haya servido.
Voy a mandar este parche a los desarrolladores de P4A a ver si lo colocan en el siguiente release, ya que el anterior que mande sobre los mensajes molestos de warnings nunca me respondieron
, a menos que me haya equivocado de correo.
Es todo por este post, nos leemos!
Tambien te puede interesar
» Leer más, comentarios, etc...
PROGRAMANDO EN .NET
Buscar en campos de texto con T-SQL: mucho más que LIKE
Mayo 8th, 2009 - [Enlace local]
Una de las primeras cosas que se aprende cuando se empieza con T-SQL es a usar la cláusula LIKE para hacer comparaciones en campos de tipo texto (char, varchar o text). Pero esta cláusula está bastante limitada y no ofrece un buen rendimiento, así que ¿qué podemos utilizar en vez de LIKE?Una muy buena opción es CONTAINS (que para ser sincero, descubrí de casualidad :P), que nos permite afinar
» Leer más, comentarios, etc...
HardBit
Agregar un menú contextual (ContextMenu) en JqGrid
Mayo 3rd, 2009 - [Enlace local]
En esta ocasión veremos como agregar un menú contextual usando un plugin que usa JQuery llamado ContextMenu a otro plugin que es un grid llamado jqGrid y que les recomiendo bastante. A diferencia de controles hechos especificamente para .Net, etc…, estos plugins son escritos completamente en Javascript con lo que podemos usar cualquier tecnologia en el backend.
Bien no voy a hablar de JQuery el programador debe tener conocimiento de este framework, en caso de no conocer pueden ir al sitio e investigar de que va, ahora si procedamos al objetivo del post.
Lo primero es crear los bindings del ContextMenu, en mi caso lo declare como una variable como lo muestra el siguiente código
El siguiente paso es agregar el menú de contexto a cada fila del grid y esto lo hacemos en el evento afterInsertRow como lo muestra el siguiente código.
Y aqui esta el resultado
Como vimos, es muy facil, funciona, en FF, IE, Chrome y Safari, salvo la excepcion con Opera, espero se pueda agregar a jqGrid antes de que salga el release de la version 3.5
Cualquier duda o comentario a [me] @ [hard-bit.net ]
» Leer más, comentarios, etc...
Blog de Julio César Pérez Arques
10 formas de mejorar tu código
Mayo 2nd, 2009 - [Enlace local]
[ACTUALIZACIÓN 030509: Añadido ejemplo de Antiobjeto.]
El otro día vi la presentación 10 Ways to Improve your Code que Neal Ford hizo en la QCon SF 2008 sobre cómo escribir mejor código y que ha publicado el portal InfoQ.
Es una presentación genial y muy práctica. Enseguida te das cuenta de que estás ante un gran programador que además sabe explicarse muy bien. Así que decidí tomar apuntes de estas 10 formas de escribir mejor código, que aprovecho para plasmar aquí y no olvidarlas.
1 - Métodos compuestos
Divide tus métodos en métodos más pequeños que realicen una única tarea claramente identificada. Así se obtiene un código más intuitivo y fácil de probar formado por métodos pequeños, cohesivos y reutilizables. Además es un código autodocumentado porque los nombres de los métodos se convierten en documentación.2 - Diseño y Desarrollo orientado a pruebas (TDD)
Piensa en cómo se usará una clase y diseñarás mejor su interfaz y su relación con otras clases.Una clase bien diseñada es fácil de probar.
3 - Análisis estático
Usa herramientas de análisis de código, como Findbugs, para evitar bugs, no violar buenas prácticas y escribir código más fácil de mantener.4 - Buenos ciudadanos
En POO los ciudadanos son las clases. Una buena clase es aquella que se relaciona bien con las demás. Un ejemplo de mal ciudadano es el Singleton. Los singletons mezclan responsabilidades (su funcionalidad más asegurar 1 única instancia), son difíciles (sino imposibles) de probar y aumentan brutalmente el acoplamiento entre clases al usarse como las antiguas variables globales. En lugar de un singleton, usa un pojo con constructor privado para la funcionalidad y haz que sea una factoría la responsable de crearlo (usando reflection para saltarse el constructor privado) y asegurarse que sólo haya 1 instancia. Más sobre el peligro de los singletons aquí.5 - YAGNI: you arent gonna need it
No programes lo que no vas a necesitar. Construye la funcionalidad más simple que necesites en cada momento.No desarrolles de forma especulativa, pensando en posibles necesidades futuras.
Me encanta esta imagen:

6 - Cuestiona el porqué
No hagas las cosas porque sí. Piensa antes y comprueba.A menudo, dentro de una empresa o equipo, se toman como leyes invariables algunas recomendaciones o soluciones concretas y circunstanciales. Incluso cuando su creador ha desaparecido. Seguro que todos tenemos algúna historia con esto...
Además a veces lo intuitivo no es cierto. Neal cita un estudio donde se observó que la programación por parejas produce código 15% menos rápido pero con 15% menos de defectos.
7 - SLAP
Usa el mismo nivel de abstracción para las líneas de un método.Así conseguirás métodos compuestos de forma natural.
8 - Programación poliglota
Domina distintos lenguajes para resolver cada problema con el lenguaje más apropiado.9 - Cada matiz
Aprende y aprovecha los matices especiales del lenguaje. Pej. en Java con reflection puedes hacer maravillas, como cambiar el modificador de acceso de métodos en tiempo de ejecución o construir objetos de clases definidas dinamicamente.10 - Antiobjetos
Solemos modelar los objetos a imagen y semejanza del mundo real. Sin embargo, en ocasiones, es útil obviar la realidad para crear soluciones menos complejas. Es lo que se conoce como antiobjetos. Por ejemplo, si pensamos en el famoso juego Pac-Man, es lógico imaginar que son los fantasmas los que calculan su camino hacia pacman en base al tablero, su posición, la de pacman y si se comió la fruta. Pero en realidad es el tablero quien mueve los fantasmas!Y tú, ¿conoces alguna otra forma?
















