window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', versión: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster ya existe') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Programación orientada a objetos. Así no se piensa - The Codest
The Codest
  • Quiénes somos
  • Servicios
    • Desarrollo de software
      • Desarrollo Frontend
      • Desarrollo backend
    • Staff Augmentation
      • Desarrolladores frontales
      • Desarrolladores de backend
      • Ingenieros de datos
      • Ingenieros de la nube
      • Ingenieros de control de calidad
      • Otros
    • Asesoramiento
      • Auditoría y consultoría
  • Industrias
    • Fintech y Banca
    • E-commerce
    • Adtech
    • Tecnología sanitaria
    • Fabricación
    • Logística
    • Automoción
    • IOT
  • Valor para
    • CEO
    • CTO
    • Gestor de entregas
  • Nuestro equipo
  • Case Studies
  • Saber cómo
    • Blog
    • Meetups
    • Seminarios en línea
    • Recursos
Carreras profesionales Póngase en contacto
  • Quiénes somos
  • Servicios
    • Desarrollo de software
      • Desarrollo Frontend
      • Desarrollo backend
    • Staff Augmentation
      • Desarrolladores frontales
      • Desarrolladores de backend
      • Ingenieros de datos
      • Ingenieros de la nube
      • Ingenieros de control de calidad
      • Otros
    • Asesoramiento
      • Auditoría y consultoría
  • Valor para
    • CEO
    • CTO
    • Gestor de entregas
  • Nuestro equipo
  • Case Studies
  • Saber cómo
    • Blog
    • Meetups
    • Seminarios en línea
    • Recursos
Carreras profesionales Póngase en contacto
Flecha atrás VOLVER
2019-05-06
Desarrollo de software

Programación orientada a objetos. Así no se piensa

Pawel Wal

Con la cantidad de recursos gratuitos, libros, clases en línea y campamentos de codificación disponibles en la actualidad, todo el mundo puede aprender a programar. Sin embargo, sigue habiendo una brecha de calidad entre la codificación y la ingeniería de software. ¿Debe haber una?

Escribí mi primer "Hola mundo" hace más de veinte años. Ésa es la respuesta que doy si alguien me pregunta cuánto tiempo hace que programo. Desde hace diez años, disfruto de una carrera que me hace tocar código casi todos los días, es la respuesta que doy si me preguntan cuánto tiempo llevo como programador profesional.

¿Desde cuándo soy ingeniero de software? Yo diría que unos cinco años. Un momento, estas cifras no me cuadran. Entonces, ¿qué ha cambiado? ¿A quién consideraría un ingeniero de software y a quién "simplemente" un programador?

Definición de ingeniero informático

Codificar es relativamente fácil. Ya no todo son mnemotécnicos en ensamblador en sistemas ridículamente limitados. Y si usas algo tan expresivo y potente como Ruby, es aún más fácil.

Simplemente coges un ticket, encuentras dónde tienes que insertar tu código, averiguas la lógica que tienes que poner ahí, y boom - listo. Si eres un poco más avanzado, te aseguras de que tu código sea bonito. Lógicamente dividido en métodos. Tiene especificaciones decentes que no sólo prueban el camino feliz. Eso es lo que hace un buen programador.

Un ingeniero de software ya no piensa en métodos y clases, al menos no principalmente. En mi experiencia, un ingeniero de software piensa en flujos. Lo primero que ven es el atronador y embravecido río de datos e interacciones que atraviesa el sistema. Piensan en lo que tienen que hacer para desviar o alterar este flujo. El código bonito, los métodos lógicos y las especificaciones geniales son casi una ocurrencia tardía.

Es tortugas todo el camino hacia abajo

La gente suele pensar de una determinada manera sobre la mayoría de las interacciones con la realidad. A falta de un término mejor, llamémoslo perspectiva "descendente". Si mi cerebro está trabajando en prepararme una taza de té, primero averiguará los pasos generales: ir a la cocina, poner la tetera, preparar la taza, verter agua, volver al escritorio.

No pensará primero en qué taza usar, mientras estoy desconectada en mi escritorio; esa desconexión vendrá después, cuando esté delante del armario. No tendrá en cuenta que puede que nos hayamos quedado sin té (o, al menos, sin la taza de té). bien cosas). Es amplio, reactivo y propenso a errores. En resumen, muy humano en la naturaleza.

A medida que el ingeniero de software considere cambios en el flujo de datos, algo alucinante, naturalmente lo hará de forma similar. Consideremos este ejemplo de historia de usuario:

Un cliente encarga un widget. A la hora de fijar el precio del pedido, hay que tener en cuenta lo siguiente:

  • Precio base del widget en la localidad del usuario
  • Forma del widget (modificador de precio)
  • Si se trata de un pedido urgente (modificador de precio)
  • Si la entrega del pedido tiene lugar en un día festivo en la localidad del usuario (modificador de precio)

Todo esto puede parecer artificioso (y, obviamente, lo es), pero no dista mucho de algunas historias reales de usuarios que he tenido el placer de aplastar recientemente.

Veamos ahora el proceso de reflexión que podría emplear un ingeniero de software para abordar esta cuestión:

"Bueno, tenemos que obtener el usuario y su pedido. Luego empezamos a calcular el total. Empezaremos en cero. Luego aplicaremos el modificador de forma del widget. Luego el cargo de urgencia. Luego vemos si es un día festivo, boom, ¡hecho antes de comer!"

Ah, el subidón que puede provocar una simple historia de usuario. Pero el ingeniero de software es humano, no una máquina multihilo perfecta, y la receta anterior es a grandes rasgos. Entonces, el ingeniero sigue pensando en profundidad:

"El modificador de forma del widget es... oh, eso depende mucho del widget, ¿no? Y pueden ser diferentes por localización, incluso si no ahora entonces en el futuro," piensan, quemados anteriormente por los cambiantes requisitos empresariales, "y el recargo de apremio también puede serlo. Y los días festivos también son muy específicos de la zona, ¡y las zonas horarias también tienen que ver! Tenía un artículo aquí sobre cómo tratar con horas en diferentes zonas horarias en Rails... ¡oh, me pregunto si la hora del pedido se almacena con la zona en la base de datos! Mejor comprobar el esquema".

Muy bien, ingeniero de software. Para. Se supone que deberías estar preparando una taza de té, pero estás absorto delante del armario pensando si la taza de flores es siquiera aplicable a tu problema del té.

Widget para preparar la taza perfecta

Pero eso es fácilmente lo que puede ocurrir cuando se intenta hacer algo tan poco natural para el cerebro humano como pensar con varios niveles de detalle. simultáneamente.

Tras rebuscar brevemente en su amplio arsenal de enlaces sobre el manejo de la zona horaria, nuestro ingeniero se recompone y empieza a descomponerlo en código real. Si intentaran el enfoque ingenuo, podría ser algo como esto:

 def calcular_precio(usuario, pedido)
   precio.pedido = 0
   order.price = WidgetPrices.find_by(widget_type: order.widget.type).price
   order.price = WidgetShapes.find_by(widget_shape: order.widget.shape).modifier
   ...
 fin

Y seguían y seguían, de esta manera deliciosamente procedimental, sólo para ser fuertemente cerrados en la primera revisión del código. Porque si lo piensas bien, es perfectamente normal pensar de esta manera: primero las grandes líneas y luego los detalles. Ni siquiera pensaste que te habías quedado sin el té bueno al principio, ¿verdad?

Nuestro ingeniero, sin embargo, está bien entrenado y no es ajeno al Objeto de Servicio, así que esto es lo que empieza a suceder en su lugar:

clase BaseOrderService
def self.call(usuario, pedido)
new(usuario, pedido).call
fin

def initialize(usuario, pedido)
@usuario = usuario
@pedido = pedido
end

def call
puts "[WARN] ¡Implementar llamada no predeterminada para #{self.class.name}!"
usuario, orden
end
end

class WidgetPriceService < BaseOrderService; end
class ShapePriceModifier < BaseOrderService; end
class RushPriceModifier < BaseOrderService; end
class HolidayDeliveryPriceModifier < BaseOrderService; end

clase OrderPriceCalculator < BaseOrderService
def call
user, order = WidgetPriceService.call(user, order)
usuario, pedido = ShapePriceModifier.call(usuario, pedido)
user, order = RushPriceModifier.call(user, order)
usuario, pedido = HolidayDeliveryPriceModifier.call(usuario, pedido)
usuario, pedido
end
end
```

Bien. Ahora podemos emplear un buen TDD, escribir un caso de prueba para él y desarrollar las clases hasta que todas las piezas encajen. Y será hermoso, también.

Además de completamente imposible de razonar.

El enemigo es el Estado

Claro, todos estos son objetos bien separados con responsabilidades únicas. Pero aquí está el problema: siguen siendo objetos. El patrón de objetos de servicio con su "fingir forzosamente que este objeto es una función" es realmente una muleta. No hay nada que impida a nadie llamar a HolidayDeliveryPriceModifier.new(usuario, pedido).algo_más_entero. Nada impide que la gente añada estado interno a estos objetos.

Por no hablar de usuario y pedir también son objetos, y jugar con ellos es tan fácil como que alguien se cuele en un rápido ordenar.guardar en algún lugar de estos objetos funcionales "puros", cambiando la fuente subyacente del estado de la verdad, es decir, una base de datos. En este ejemplo artificial no es un gran problema, pero seguro que puede volverse en tu contra si este sistema crece en complejidad y se expande en partes adicionales, a menudo asíncronas.

El ingeniero tenía la idea correcta. Y utilizó una forma muy natural de expresar esta idea. Pero saber cómo expresar esta idea -de una forma bella y fácil de razonar- estaba casi impedido por el paradigma de programación orientada a objetos subyacente. Y si alguien que todavía no ha dado el salto a expresar sus pensamientos como desviaciones del flujo de datos intenta alterar con menos habilidad el código subyacente, pasarán cosas malas.

Pureza funcional

Ojalá existiera un paradigma en el que expresar tus ideas en términos de flujos de datos no sólo fuera fácil, sino necesario. Si el razonamiento pudiera simplificarse, sin posibilidad de introducir efectos secundarios no deseados. Si los datos pudieran ser inmutables, como la florida taza en la que te preparas el té.

Sí, estoy bromeando, por supuesto. Ese paradigma existe, y se llama programación funcional.

Veamos cómo quedaría el ejemplo anterior en uno de nuestros favoritos, Elixir.

defmodule WidgetPrecios do
def preciopedido([usuario, pedido]) do
[usuario, pedido]
|> widgetprecio
|> modificador de precio de forma
|> modificador precio rush
|> modificador precio vacaciones
fin

defp widgetprecio([usuario, pedido]) do
%{widget: widget} = pedido
precio = WidgetRepo.getbase_price(widget)
[usuario, %{pedido | precio: precio }]
end

defp shapepricemodifier([usuario, pedido]) do
%{widget: widget, precio: precio actual} = pedido
modificador = WidgetRepo.getshapeprice(widget)
[usuario, %{pedido | precio: precio actual * modificador} ]
end

defp rushpricemodifier([usuario, pedido]) do
%{prisa: prisa, precio: precio actual} = pedido
if rush do
[usuario, %{pedido | precio: precio actual * 1,75} ]
else
[usuario, %{pedido|precio: precio_actual} ]
end
end

defp modificadorpreciosvacaciones([usuario, pedido]) do
%{fecha: fecha, precio: precio_actual} = pedido
modificador = HolidayRepo.getholidaymodifier(usuario, fecha)
[usuario, %{pedido | precio: precio actual * modificador}].
end
end
```

Puedes notar que es un ejemplo completo de cómo la historia de usuario se puede lograr realmente. Esto se debe a que es menos complicado que en Ruby. Estamos utilizando algunas características clave exclusivas de Elixir (pero generalmente disponibles en lenguajes funcionales):

Funciones puras. En realidad no cambiamos la entrada pedir en absoluto, sólo estamos creando nuevas copias - nuevas iteraciones sobre el estado inicial. Tampoco saltamos a un lado para cambiar nada. E incluso si quisiéramos, pedir es sólo un mapa "tonto", no podemos llamar a ordenar.guardar en cualquier punto aquí porque simplemente no sabe lo que es.

Coincidencia de patrones. De forma bastante similar a la desestructuración de ES6, esto nos permite arrancar precio y widget de la orden y pasarla, en lugar de forzar a nuestros compañeros WidgetRepo y HolidayRepo para saber cómo hacer frente a una pedir.

Operador de tuberías. Visto en orden_precionos permite pasar datos a través de funciones en una especie de "pipeline" - un concepto inmediatamente familiar para cualquiera que haya ejecutado alguna vez ps aux | grep postgres para comprobar si la maldita cosa seguía funcionando.

Así es como piensas

Los efectos secundarios no son realmente una parte básica de nuestro proceso de pensamiento. Después de verter agua en la taza, no solemos preocuparnos de que un error en la tetera pueda hacer que se sobrecaliente y explote, al menos no tanto como para ir a hurgar en sus entrañas para comprobar si alguien no ha dejado inadvertidamente... explotar_después_de_verter en alto.

El camino que lleva de programador a ingeniero de software -pasar de preocuparse por objetos y estados a preocuparse por flujos de datos- puede llevar años en algunos casos. A mí, por ejemplo, me llevó años. Con los lenguajes funcionales, empiezas a pensar en flujos en tu primera noche.

Hemos hecho ingeniería de software complicado para nosotros y para todos los recién llegados al campo. La programación no tiene por qué ser difícil y complicada. Puede ser fácil y natural.

No nos compliquemos y vayamos ya a lo funcional. Porque así es como pensamos.

Lea también:

  • ¿Por qué la tecnología acelera el crecimiento del comercio electrónico, los marketplaces y las empresas SaaS?
  • ¿Por qué Ruby on Rails es una buena opción para el desarrollo de software? Mi opinión personal

Artículos relacionados

Desarrollo de software

Crear aplicaciones web preparadas para el futuro: ideas del equipo de expertos de The Codest

Descubra cómo The Codest destaca en la creación de aplicaciones web escalables e interactivas con tecnologías de vanguardia, ofreciendo experiencias de usuario fluidas en todas las plataformas. Descubra cómo nuestra experiencia impulsa la transformación...

EL MEJOR
Desarrollo de software

Las 10 mejores empresas de desarrollo de software de Letonia

Conozca las principales empresas de desarrollo de software de Letonia y sus innovadoras soluciones en nuestro último artículo. Descubra cómo estos líderes tecnológicos pueden ayudarle a mejorar su negocio.

thecodest
Soluciones para empresas y escalas

Fundamentos del desarrollo de software Java: Guía para externalizar con éxito

Explore esta guía esencial sobre el desarrollo de software Java outsourcing con éxito para mejorar la eficiencia, acceder a la experiencia e impulsar el éxito de los proyectos con The Codest.

thecodest
Desarrollo de software

La guía definitiva para subcontratar en Polonia

El auge de las outsourcing en Polonia está impulsado por los avances económicos, educativos y tecnológicos, que fomentan el crecimiento de las TI y un clima favorable a las empresas.

TheCodest
Soluciones para empresas y escalas

Guía completa de herramientas y técnicas de auditoría informática

Las auditorías informáticas garantizan sistemas seguros, eficientes y conformes. Obtenga más información sobre su importancia leyendo el artículo completo.

The Codest
Jakub Jakubowicz CTO y Cofundador

Suscríbase a nuestra base de conocimientos y manténgase al día de la experiencia del sector informático.

    Quiénes somos

    The Codest - Empresa internacional de desarrollo de software con centros tecnológicos en Polonia.

    Reino Unido - Sede central

    • Oficina 303B, 182-184 High Street North E6 2JA
      Londres, Inglaterra

    Polonia - Centros tecnológicos locales

    • Parque de oficinas Fabryczna, Aleja
      Pokoju 18, 31-564 Cracovia
    • Embajada del Cerebro, Konstruktorska
      11, 02-673 Varsovia, Polonia

      The Codest

    • Inicio
    • Quiénes somos
    • Servicios
    • Case Studies
    • Saber cómo
    • Carreras profesionales
    • Diccionario

      Servicios

    • Asesoramiento
    • Desarrollo de software
    • Desarrollo backend
    • Desarrollo Frontend
    • Staff Augmentation
    • Desarrolladores de backend
    • Ingenieros de la nube
    • Ingenieros de datos
    • Otros
    • Ingenieros de control de calidad

      Recursos

    • Hechos y mitos sobre la cooperación con un socio externo de desarrollo de software
    • De EE.UU. a Europa: ¿Por qué las startups estadounidenses deciden trasladarse a Europa?
    • Comparación de los polos de desarrollo de Tech Offshore: Tech Offshore Europa (Polonia), ASEAN (Filipinas), Eurasia (Turquía)
    • ¿Cuáles son los principales retos de los CTO y los CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Condiciones de uso del sitio web

    Copyright © 2025 por The Codest. Todos los derechos reservados.

    es_ESSpanish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean nl_NLDutch etEstonian elGreek es_ESSpanish