¿Los objetos en OOP tienen que representar una entidad?

82

¿Un objeto tiene que representar una entidad?

Por una entidad que quiero decir algo así como un Product, Motoruna ParkingLot, etc, un examen físico, o incluso un objeto conceptual no física clara - algo que está bien definido, con algunos datos básicos que pertenece claramente al objeto, y algunas funciones / métodos que claramente operan en los datos centrales.

Por ejemplo, puedo tener un objeto de a Demon, una entidad en sí misma, una imaginaria quizás y no física, pero una entidad no obstante

¿Puede un objeto ser solo una colección de métodos , un conjunto común de procedimientos que se vinculan con un objetivo común?

Ejemplo: se puede llamar a una clase MotorOperationso MotorActions, donde no hay entidad, pero los métodos dentro de la clase hacen cosas como

  • getMotorDataFromHTMLForm ()
  • getMotorManufacturers ()
  • selectMotorFromUserRequirements ($ requisitos)
  • canMotorCanHandleOperatingConditions ($ condiciones)
  • computePowerConsumptionForMotor ($ id)

Una clase se define típicamente como datos centrales para el objeto + operaciones en los datos. Entonces, para un Motorpuede haber algunas variables del motor relacionadas con las especificaciones del motor, y puede haber operaciones que combinen esos datos para producir algo.

En mi caso, es más como si tuviera una clase con operaciones en datos + datos que se pasan a través de la clase, no hay datos centrados en "Motor Operations", aparte de los datos temporales de paso a través de la clase.

Pregunta

¿Pueden las clases representar objetos sin entidad? Si no, ¿por qué son malos / incompletos / no centrados en OOP? ¿Hay formas en que deben cambiarse / mejorarse conceptualmente para estar en línea con OOP?

Dennis
fuente
2
+1. ¿Pero "sí" significaría que tiene que representar una entidad, o significaría que pueden representar objetos sin entidad?
Panzercrisis
1
Lo primero que me viene a la mente: java.awt y sus clases "Op" (por ejemplo, docs.oracle.com/javase/7/docs/api/java/awt/image/… ), si eso es lo que quieres decir. Representa una operación. Ahora, no estoy seguro de si es una buena práctica (se ve raro y feo), pero está incluido en la biblioteca estándar de Java, y Java es POO. En la mayor parte.
Lucas
1
No, no lo hace, pero eso no significa MotorActionso MotorOperationsson buenas ideas o no.
user253751
1
Esta pregunta podría beneficiarse de una especificación adicional de lata .
reinierpost
3
@ Dennis Realmente siento que estás haciendo todas las preguntas equivocadas. Primero porque no hay una definición definitiva de OOP, segundo porque los paradigmas son solo un medio para un fin. Las únicas preguntas que importan son "¿escribir código de esta manera hace que sea más fácil razonar sobre su corrección?" y "¿escribir código de esta manera facilita la reutilización?"
Doval

Respuestas:

109

No , un objeto no tiene que representar una entidad.

De hecho, diría que cuando dejas de pensar en los objetos como entidades físicas es cuando finalmente obtienes los beneficios que promete OOP.

Este no es el mejor ejemplo, pero el diseño de la cafetera es probablemente donde la luz comenzó a encenderse para mí.

Los objetos son sobre mensajes. Se trata de responsabilidades. No se trata de automóviles, usuarios u órdenes.

Sé que enseñamos a OO de esta manera, pero después de algunos intentos se hace evidente cuán fundamentalmente frustrante es descubrir adónde van las cosas cuando intentas hacer MVC, MVVM o MVWhatever. O tus modelos se vuelven ridículamente hinchados o tus controladores lo hacen. Para la navegabilidad, es bueno saber que todo lo que toca Vehículos está en el archivo Vehicle.ext, pero cuando su aplicación es sobre Vehículos, inevitablemente termina con 3000 líneas de espagueti en ese archivo.

Cuando tiene que enviar un nuevo mensaje, tiene al menos un nuevo objeto, y quizás un par de ellos. Entonces, en su pregunta sobre un conjunto de métodos, diría que potencialmente está hablando de un conjunto de mensajes. Y cada uno podría ser su propio objeto, con su propio trabajo que hacer. Y eso esta bien. Será evidente a medida que separas las cosas que realmente necesitan estar juntas. Y los pones juntos. Pero no deja caer inmediatamente todos los métodos en un cajón vagamente apropiado por razones de conveniencia si desea disfrutar de OO.

Hablemos de bolsas de funciones.

Un objeto puede ser solo una colección de métodos y seguir siendo OO, pero mis "reglas" son bastante estrictas.

  1. La colección debe tener una única responsabilidad, y esa responsabilidad no puede ser tan genérica como "Hace cosas a los motores". Podría hacer algo como una fachada de capa de servicio, pero soy muy consciente de que soy flojo por razones de navegación / descubrimiento, no porque esté tratando de escribir código OO.

  2. Todos los métodos deben estar en una capa consistente de abstracción. Si un método recupera objetos de Motor y otro devuelve Caballos de fuerza, probablemente eso esté demasiado separado.

  3. El objeto debería funcionar en el mismo "tipo" de datos. Este objeto hace cosas a los motores (inicio / parada), este hace cosas con longitudes de manivela, este maneja la secuencia de encendido, este toma una forma html. Estos datos podrían ser campos del objeto y parecería coherente.

Generalmente construyo objetos de este tipo cuando estoy haciendo transformaciones, composición, o simplemente no quiero preocuparme por la mutabilidad.

Creo que centrarme en las responsabilidades objetivas me lleva a la cohesión. Tiene que haber cierta cohesión para ser un objeto, pero no es necesario que haya ningún campo ni mucho comportamiento para que sea un objeto. Si estuviera construyendo un sistema que necesitara esos 5 métodos motores, comenzaría con 5 objetos diferentes que hacen esas cosas. A medida que encontraba algo en común, comenzaba a fusionar las cosas o a usar objetos "auxiliares" comunes. Eso me lleva a inquietudes abiertas / cerradas: ¿cómo puedo extraer este bit de funcionalidad para que nunca tenga que modificar ese archivo en particular nuevamente pero aún así usarlo donde sea necesario?

Los objetos son sobre mensajes

Los campos apenas le importan a un objeto: obtener y establecer registros no cambia el mundo fuera del programa. Colaborar con otros objetos hace el trabajo. Sin embargo, la fortaleza de OO es que podemos crear abstracciones para no tener que pensar en todos los detalles individuales a la vez. Las abstracciones que se filtran o no tienen sentido son problemáticas, por lo que pensamos profundamente (demasiado, tal vez) sobre la creación de objetos que coincidan con nuestros modelos mentales.

Pregunta clave: ¿Por qué estos dos objetos necesitan comunicarse entre sí?

Piense en el objeto como un órgano en una persona: tiene un propósito predeterminado y solo cambia el comportamiento cuando recibe un mensaje específico que le interesa.

Imagina un escenario en el que estás en el cruce de peatones y un automóvil viene rápido. Como objeto del cerebro, detecto un factor estresante. Le digo al hipotálamo que envíe hormona liberadora de corticotropina. La glándula pituitaria recibe ese mensaje y libera la hormona corticotrófica suprarrenal. Las glándulas suprarrenales reciben ese mensaje y crean adrenalina. Cuando el objeto muscular recibe ese mensaje de adrenalina, se contrae. Cuando el corazón recibe el mismo mensaje, late más rápido. Hay toda una cadena de jugadores involucrados en comenzar el comportamiento complejo de correr a toda velocidad en la calle y son los mensajes lo que importan. El objeto cerebral sabe cómo hacer que el hipotálamo envíe la alerta, pero no conoce la cadena de objetos que eventualmente harán que el comportamiento suceda. Del mismo modo, el corazón no tiene idea de dónde viene la adrenalina,

Entonces, en este ejemplo ( simplificado ), el objeto de la glándula suprarrenal solo necesita saber cómo tomar ACTH y producir adrenalina. No necesita ningún campo para hacer eso, sin embargo, todavía me parece un objeto.

Ahora, si nuestra aplicación está diseñada solo para correr a través de la calle, es posible que no necesite la glándula pituitaria y los objetos de la glándula suprarrenal. O solo necesito un objeto de glándula pituitaria que solo haga una pequeña parte de lo que conceptualmente podríamos ver como el "modelo de glándula pituitaria". Todos estos conceptos existen como entidades conceptuales, pero es software y podemos hacer AdrenalineSender o MuscleContractor o lo que sea y no preocuparnos mucho por la "incompletitud" de nuestro modelo.

Steve Jackson
fuente
44
Estoy de acuerdo con el contenido real de esta respuesta, pero siento que no comprende la pregunta. Específicamente, la pregunta incluye en la entidad "o un concepto, algo que está bien definido". Los contraejemplos de esto son " MotorOperationso MotorActions". A partir de esto, estoy bastante seguro de que tanto los diseños de clase originales como los finales del ejemplo CoffeeMaker caen bajo la definición del OP de "representar una entidad"
Ben Aaronson
1
La arquitectura del sistema posmoderno DCI maneja esto sin las extremas abstracciones creadas por ingenieros amantes de la estructura. La computadora debe pensar lo que piensa el usuario, no al revés. fulloo.info/doku.php?id=what_is_dci
ciscoheat
@BenAaronson Siento que puedes evolucionar a ese objeto como un concepto coherente con suficiente esfuerzo concertado, pero he encontrado una tendencia a que el enfoque de la entidad fuerce las cosas juntas que deberían estar separadas. Las entidades fomentan los límites en nuestros nombres, lo cual es bueno, pero también traen consigo esta noción de corrección / integridad, que tiende a doler. En los términos más ridículos, estoy a favor de un objeto FirstNameValidator y contra un objeto Name que también valida para nombres y apellidos.
Steve Jackson
2
Los objetos son sobre mensajes - la respuesta de Steve Jackson - esto es absolutamente correcto. MOP no es lo que se entiende por "mensaje" como lo concibió el padre de OO Alan Kay, quien dijo que la gran idea es el mensaje . Además, lamento haber acuñado hace mucho tiempo el término "objetos" para este tema porque hace que muchas personas se centren en la idea menor.
radarbob
21

¿Pueden las clases representar objetos sin entidad? Si no, ¿por qué son malos / incompletos / no centrados en OOP? ¿Hay formas en que deben cambiarse / mejorarse?

En resumen, puede hacer cualquier cosa, pero este escenario específico estaría en contra de los principios de OOP :)

Lo que está describiendo a veces se llama una clase de "utilidad", generalmente una señal de olor a código. Desea evitar crear clases en aras de mantener algunos métodos juntos.

No todos los objetos en su aplicación tienen que estar vinculados a una entidad de la vida real como un motor o automóvil; Esos son objetos de negocios. En su aplicación, es probable que utilice muchos de sus objetos comerciales, pero también necesitará más segregación para otras operaciones que no forman parte de las entidades comerciales, como las que enumeró.

Debería echar un vistazo a los patrones arquitectónicos comunes, uno de ellos es MVC (Model-View-Controller) .

Si tuviera que distribuir los métodos que enumeró usando MVC, esto es lo que haría:

Ver clase:

  • GetMotorDataFromHTMLForm ()

Clase de modelo (motor esencialmente):

  • GetMotorManufacturer ()
  • CanMotorHandleOperationConditions ()
  • CalculatePowerConsumption ()

Clase de controlador (MotorsController):

  • GetAllMotors ()
  • GetMotorById ()
  • GetMotorByUserRequirements ()

Parece que estás usando PHP; Un buen marco MVC para echar un vistazo es Laravel . En sus ejemplos, ilustran bien a qué métodos pertenecen.

Otra fuente de información más genérica sobre cómo decidir dónde pertenecen los métodos son los principios GRASP y SOLID .

Alexus
fuente
Gracias. En esencia, me parece que lo que tengo es una clase de Controlador con algunas impurezas mezcladas (Modelo, Vista, etc.). ¿Eso quiere decir que si puedo cambiar el nombre MotorOperationsde MotorsControllery limpiarlo un poco, mi colección de funciones estará en línea con la programación orientada a objetos?
Dennis
@Dennis, no necesariamente, eche un vistazo a mi colección de métodos en cada clase. El controlador no es una clase que lo contiene todo :) Es la clase que opera en sus modelos, y nada más. Las únicas dependencias de un controlador generalmente serían DAL (Data Access Layer) directamente, o servicios que le brindan acceso a DAL. Nunca desea acceder a la Vista desde el controlador (ejemplo: getMotorDataFromHTMLForm), en cambio, su Vista debería ser la que depende del controlador.
Alexus
2
¿Podría explicar por qué una Utilsclase sería un ejemplo de olor a código? Es curioso, ya que disfruté tener funciones de utilidad aleatorias incluidas en una Utilsclase en lugar de ser funciones independientes ... en mi experiencia, hace que el código sea un poco más legible, pero mi experiencia es limitada.
HC_
3
@HC_ Tener una clase Utils es lo mismo que tener una carpeta "Misc" en su colección de imágenes. Indica que usted fue perezoso para asignar responsabilidades a sus objetos adecuadamente / objetos potencialmente perdidos y usar Utils para compensar eso. Hay un espacio para las clases de Util, especialmente con funciones estáticas y extensiones a otras clases, pero antes de crear una colección como esa, verifique si puede incorporarlas a sus clases OOP adecuadas :) Otra razón es que a veces una clase solo puede tener Un método Pero en el futuro, debe agregar más y la clase Utils se convierte en un desastre mayor.
Alexus
A menudo termino con una BIBLIOTECA de utilidades, pero generalmente trato de agrupar y nombrar mis clases de utilidades de manera un poco más descriptiva. En estos días, hay muchas bibliotecas de "utilidades comunes" de código abierto que ya tienen utilidades de uso general que la mayoría de las personas necesitan, por lo que debería mirar un poco antes de escribir la suya.
Guy Schalnat
15

¿Pueden las clases representar objetos sin entidad?

¿Lata? Si. ¿Debería? Probablemente no, o al menos, no cómo estás redactando cosas.

Los objetos en realidad son mejores cuando no representan un objeto físico directamente, ya que la realidad se asigna muy poco al código. Pero sí necesitan representar un concepto coherente o un objeto de código. Necesitan representar una responsabilidad cohesiva única.

Solo agrupar un conjunto de funciones relacionadas tangencialmente es un espacio de nombres o un módulo, no un objeto en el lenguaje OOP. Esos pueden ser útiles, pero no son lo mismo y requieren un tipo diferente de uso / pensamiento para trabajar con eficacia.

Telastyn
fuente
3
bundling a bunch of tangentially related functions together is a namespace: eso suena más como un paradigma de procedimiento que como un objeto orientado.
Dennis
@dennis: exactamente (o funcional si lo llama Módulo). La mezcla de paradigmas puede ser poderosa. O puede ser terriblemente desordenado.
Telastyn
O ambos :) - - - - -
Alexus
@Dennis: O tampoco: agrupar solo funciones relacionadas tangencialmente es una práctica dudosa en cualquier paradigma.
sdenham
Estoy tratando con un código que comenzó como una base de código de procedimiento. En algún momento se hizo un esfuerzo para convertirlo a OOD pero, en su mayoría, las clases se crearon para "mantener funciones y métodos", sin ningún diseño OO real. He estado descubriendo bastantes cosas como esta que intentan cerrar la brecha entre los paradigmas pero no están ni en uno ni en otro
Dennis
11

Una clase debería modelar algo ; de lo contrario, no tiene sentido. Sin embargo, lo que se está modelando puede no ser una "cosa" física; en cambio, puede ser una representación de algo que no es "real", pero que es necesario para controlar el sistema que se está modelando. Por ejemplo, en un sistema de control de semáforo, podría tener algún tipo de clase ControlSignal, que representa una señal enviada desde una parte del sistema a otra para indicar que es necesario realizar alguna acción. En "el mundo real", estas señales pueden consistir en impulsos eléctricos transmitidos a través de cables de una caja a otra. El proceso de modelar algo que no es "real" como un objeto concreto se denomina "reificación".

La mejor de las suertes.

Bob Jarvis
fuente
Sí, eso es casi exactamente lo que hubiera dicho. Una clase no es más que un modelo para un sustantivo . Eso es. Nada más y nada menos. Una clase es un sustantivo, y los métodos son verbos (o mensajes si lo prefiere). Un ingeniero junior que piense en esos términos simples puede recorrer un largo camino antes de que esas analogías se rompan (a diferencia de tratar de pretender que las clases son descripciones de objetos físicos, una analogía que comienza a romperse en casi su primer proyecto).
Calphool
7

No. (¡Título editado para hacer la pregunta opuesta!)

p.ej:

Public class MyRepository
{
    public MyObject GetObject(string id)
    {
        //get data from the DB and build an object
    }
}

o

Public class MyService
{
    public MyObject3 ProcessData(MyObject1 obj1, MyObject2 obj2)
    {
         //perform a process which is not a sole responsiblity of obj1 or obj2
    }
}

Sin embargo, en general, el ideal detrás de OOP es alejarse de

public struct Car
{
    public Wheel[] Wheels;
}

public int CountWheelsOnCar(MyCarStruct car)
{
   return car.Wheels.Length;
}

a

public class Car
{
    private Wheel[] wheels;
    Public int CountWheels()
    {
        return this.wheels.Length;
    }
}
Ewan
fuente
¿Quiere decir que pueden representar objetos sin entidad? (Ver el comentario que dejé sobre la pregunta.)
Panzercrisis
3
Supongo que he estado programando OO demasiado tiempo. Cuando miré en MyRepository, inmediatamente imaginé un recipiente de vidrio en mi tocador con un montón de monedas y basura. Acércate y saca un centavo, o un botón ...
Bill K
@pan sí, como el servicio y el repositorio en mi ejemplo
Ewan
@Bill, viejo loco! ¡Esa es la clase MyButtonAndOrPennyBowl! codificación limpia ftw
Ewan
1
Su segundo ejemplo me parece una función vestida como un objeto, que (en mi opinión) no está justificada por sí misma, aunque puede haber alguna otra justificación (por ejemplo, si las funciones no son entidades de primera clase en el lenguaje). )
sdenham
5

Creo que visualizar algo en el mundo real es útil cuando se codifican clases, pero no es necesario.

De hecho, dependiendo de cuán literal quieras ser, muchos objetos con los que trabajamos no tienen representaciones físicas en absoluto. Por ejemplo, considere la arquitectura MVC. En el mundo real no hay Modelo o Controlador, aunque generalmente están representados por clases. Los tres juntos a menudo representan algo, pero no siempre, pero como dije, probablemente podrías forzar un ajuste en algo si realmente quieres (¡y poder imaginar que ALGO ayuda! Visualizo la mayoría de los objetos de alguna manera, simplemente no nada alguna vez verías en el mundo real).

En su mayoría, estas "Reglas" que aprenderá sobre OO son solo pautas destinadas a orientarlo a pensar en OO, no necesariamente cosas que le preocupan mucho una vez que lo usa para codificar a diario.

Por cierto, OO en sí no es una panacea y no te ayuda en absoluto durante tu primer paso para codificar alguna solución, pero creo que si se hace bien, es una forma realmente fantástica de organizar el código para que pueda ser más fácilmente entendido más tarde. Escribir código mantenible es probablemente una de las tareas más difíciles en el desarrollo de software y en muchos casos (cualquier cosa que requiera depuración / mantenimiento continuo) es, con mucho, el más importante.

Bill K
fuente
5

¿Un objeto tiene que representar una entidad?

Pregunta: ¿Qué entidad Loggerrepresenta un ?

No metafóricamente, literalmente.

Al explicar OOP a los estudiantes, es útil explicar objetos con analogías al mundo físico.

Alan Kay , uno de los padres de OOP , escribió lo siguiente:

[...]

La concepción original de la misma tenía las siguientes partes.

  • Pensé en objetos como células biológicas y / o computadoras individuales en una red, solo capaces de comunicarse con mensajes
  • Quería deshacerme de los datos.

[...]

OOP para mí significa solo mensajes, retención y protección local y

ocultación del proceso de estado, y un enlace tardío extremo de todas las cosas.

arquitectura de HW casi increíble. Me di cuenta de que el

la metáfora celular / computadora completa eliminaría los datos

fuente

A partir de esto, los objetos se entienden mejor como

  • objetos autárquicos que encapsulan / ocultan datos

  • comunicarse con otros objetos a través de mensajes

¿Pueden las clases representar objetos sin entidad?

Definitivamente: piensa en Math


En cuanto a su ejemplo:

Ejemplo: una clase puede llamarse MotorOperations o MotorActions, donde no hay entidad, pero los métodos dentro de la clase hacen cosas como

  • getMotorDataFromHTMLForm ()

  • getMotorManufacturers ()

  • selectMotorFromUserRequirements ($ requisitos)

  • canMotorCanHandleOperatingConditions ($ condiciones)

  • computePowerConsumptionForMotor ($ id)

Para decidir dónde colocar estos métodos, debe mirar responsibilities: quién es responsable de qué .

getMotorDataFromHTMLForm ()

El contexto de tal método sería construir un motor-objeto . No es responsabilidad del motor crearse a partir de los datos recuperados a través de un formulario . Hay al menos dos objetos involucrados; uno es el motor y el otro es el creador del motor .

getMotorManufacturers ()

El contexto típico en el que uno escribiría tal método es a service.

selectMotorFromUserRequirements ($ requisitos)

Esto también se usaría en un servicecontexto

canMotorCanHandleOperatingConditions ($ condiciones)

Esta es una pregunta a un motor-objeto

computePowerConsumptionForMotor ($ id)

Esta también es una pregunta que se hace mejor a un motor.


tl; dr

La metáfora de objectscomo objetos físicos es más irritante que útil.

Thomas Junk
fuente
wow tu respuesta da un poco de vida a OOP Tengo que decir que no quise decir física como un final para todo. La intención de mi pregunta era más "¿un objeto tiene que ser un thingcon datos donde los datos claramente pertenecen a la cosa y las funciones que operan claramente en los datos que pertenecen a la cosa". Entonces, Logger en este caso, aunque no es algo físico, es un concepto similar al de un "libro de registro físico". Si tiene datos que son fundamentales para su estado, y no solo transitorios, puede depender de la implementación e interpretación ... y más aún hacia dónde iba mi pregunta ...
Dennis
pero sí, las respuestas tenían que abordar mi sesgo físico
Dennis
3

Sí, usted puede hacer esto. Pero esencialmente está creando una clase para proporcionar la misma funcionalidad que una biblioteca de procedimientos. La única razón para hacerlo es si su idioma carece de módulos de procedimiento (por ejemplo, Java o Ruby).

En un lenguaje con módulos de procedimiento (creo que PHP tiene módulos de procedimiento), podría considerar simplemente usar un módulo de procedimiento.

También podría considerar rediseñar su clase para que una instancia de la clase represente un objeto coherente.

¡Pero solo usa la notación OO cuando te da poder extra, no solo por el hecho de ser OO!

Jonathan Cast
fuente
3

En palabras simples

  • Lo que describe se llama una clase de utilidad.
  • No tiene estado, lo que significa que nunca necesitará tener varias instancias de él.
  • Todos los métodos son estáticos, lo que significa que debe pasar todo como parámetros

Estas clases existen, por ejemplo, el SDK de Java tiene la clase Colecciones que consiste exclusivamente en métodos estáticos que operan en colecciones o las devuelven.

Entonces la respuesta sería no, no todas las clases necesitan ser modeladas a partir de una entidad de dominio.

Por otro lado, tales clases son solo unas pocas o deberían ser solo unas pocas en un programa hecho en un lenguaje OOP, ya que el verdadero poder de la OOP reside en el polimorfismo y la encapsulación.

Sería como usar un avión para ir de un lugar a otro, no volando, sino conduciéndolo por las autopistas. Los aviones tienen ruedas como los automóviles, pero están destinados a volar.

Tulains Córdova
fuente
2

No, una clase simplemente representa algo que puede ser instanciado, tiene miembros y de donde se puede heredar.

De hecho, su idioma puede tener clases estáticas, que ni siquiera se instancian más de una vez.

.NETMath es un gran ejemplo de una clase "profesional" que no representa a ninguna entidad (a menos que quiera ser filosófico sobre lo que son las matemáticas ...), y también ilustra un caso de uso legítimo de dicha clase. Tiene solo métodos y 2 campos (ambos representan constantes individuales).

La jerarquía de clases de una biblioteca similar Math.Net, agrupa métodos matemáticos / numéricos en clases por tipo. Aquí las clases no representan una entidad, sino una categoría lógica.

Yo mismo a menudo termino creando clases (estáticas) que no son más que una bolsa de funciones relacionadas (estáticas), o un grupo de constantes convenientemente agrupadas en un lugar central. No diría que este es un buen diseño, pero a veces es la solución más sencilla.

Superbest
fuente
1
El hecho de que los métodos relacionados con las matemáticas se coloquen en .NET / BCL en una clase separada como métodos estáticos no es una necesidad o una consideración de diseño, sino una consecuencia del hecho de que no hay métodos independientes en C #. En C ++, tales funciones podrían agruparse en un espacio de nombres.
Vlad
1

Las respuestas a sus preguntas dependen en última instancia de cuán precisamente se definen términos como "clase" y "entidad". Hiciste un buen trabajo definiendo lo último, permitiendo tanto entidades físicas como conceptuales. Pero el término "clase" para los puristas siempre será "una fábrica para crear instancias de objetos con una representación interna particular" y para los pragmáticos el término abarcará aquellas cosas Java o C ++ despreciadas por los puristas. Lo mismo ocurre con el término "OOP", que los pragmáticos podrían decir que hacen Java y C ++, pero que los puristas tomarían en el sentido de lo que Alan Kay quiso decir cuando comentó ["Inventé el término orientado a objetos, y puedo decirte que no lo hice". tener C ++ en mente "] ( Entonces, ¿qué * quiso decir * Alan Kay realmente con el término" orientado a objetos "? ).

Si toma la vista pragmática, puede aceptar sus clases de utilidad sin instancia. Pero la visión purista es más interesante. OOP, según Kay, siempre fue más sobre los mensajes que las clases. Entonces a sus preguntas:

¿Pueden las clases representar objetos sin entidad?

No. Las clases clasifican objetos. Las clases son, por definición, aquellas entidades a las que envía un mensaje, como newpara producir un objeto. Un objeto es una entidad hecha de una clase. Las clases existen para fabricar y, de hecho, clasificar objetos. Eso es lo que hacen las clases. Las clases hacen objetos. Usamos clases para clasificar objetos. Entonces, si C es solo un conjunto de métodos que no permite la creación de instancias o subclases, no puede haber ningún objeto clasificado por C, por lo que C no es una clase.

Si no, ¿por qué son malos / incompletos / no centrados en OOP?

No estan mal. Simplemente no los llames clases. Un conjunto de métodos es OOPable: algo a lo que podría enviar un mensaje para invocar un método, pero no es una clase a menos que pueda crear una instancia de un objeto. ¿Conoces a Ruby? En Ruby, un módulo es un conjunto de métodos. Una clase es un módulo que puede instanciar objetos. No hay nada malo en un módulo . Pero lo que hace que una clase sea diferente de un módulo (en términos OOP puros) es que una clase puede tener instancias. Un módulo es solo algunos métodos. La confusión es que C ++ y Java y otros lenguajes usan el término "clase" tanto para clase como para módulo .

Ahora, para ver uno de sus ejemplos específicos, pregunta acerca de una MotorOperationsclase a la que podría enviar el mensaje computePowerConsumptionForMotorcon argumento id. ¿Es tan malo? Al menos no viola el Principio Tell Don't Ask . Es lo que tenemos que hacer una clase de motor y enviarlo al powerConsumptionmensaje? Tal vez no el 100% del tiempo, pero tal vez intentar hacer esas cosas dará lugar a algunas buenas ideas sobre su código. O bien, puede conducir a una explosión de pequeñas clases que serían malas.

¿Hay formas en que deben cambiarse / mejorarse conceptualmente para estar en línea con OOP?

Si "hacer OOP" es importante para usted, entonces querrá buscar formas de diseñar un sistema en componentes que se comuniquen enviándose mensajes entre sí. Eso es exactamente lo que es OOP , o al menos lo que tenía en mente el inventor del término. Las clases de utilidad no son OOP en esta vista. Pero para algunas personas, pueden ser.

Intentar hacer un gran sistema completo de millones de objetos vivos, respiratorios, todos instanciados de clases, puede funcionar para algunos proyectos. Pero si te encuentras creando clases artificiales que suenan mal, entonces los módulos deberían ser introducidos. Intente enfatizar las clases y use módulos cuando las clases instanciables serían ridículas.

TL; DR: los paquetes de métodos no siempre son malos. Intente usar clases instanciables primero. Vuelva a "módulos" solo cuando sea necesario.

Ray Toal
fuente
0

Tomando los ejemplos dados:

getMotorDataFromHTMLForm()
selectMotorFromUserRequirements($requirements)

Estos parecen métodos de "fábrica", que devolverían un Motorobjeto. El segundo implica que está creando un nuevo objeto para cumplir con los requisitos, o tiene una base de datos o una colección en memoria de motores que está examinando. En cuyo caso debería ser un método para eso. O podría ser un método en el objeto de requisitos.

getMotorManufacturers()

¿De dónde los sacas? De eso debería ser un método.

canMotorCanHandleOperatingConditions($conditions)
computePowerConsumptionForMotor($id)

Parece que deberían ser métodos Motor.

pjc50
fuente
Si. es un "paquete de métodos posiblemente no relacionados" (BOPUM para abreviar). Estoy de acuerdo con los comentarios de Factory y Motor. getMotorManufacturerses devolver a todos los fabricantes de motores de la base de datos. No estoy seguro de a dónde va eso. Me llevará algún tiempo desentrañar este BOPUM para poner las cosas donde tienen que ir ...
Dennis
Estoy obteniendo getMotorManufacturersde la base de datos. La base de datos no puede tener un método ... Actualmente tengo un patrón DataMapper que consulta la base de datos, inicializa una matriz y la llena con objetos de motor (que también contienen información del fabricante), y luego devuelve esa matriz a la persona que llama. La persona que llama es mi MotorOperationsclase, que a su vez se llama desde una ProductSelectionclase (que contiene un algoritmo que se utiliza para seleccionar Motores, y la información del motor cargado son los datos para ese algoritmo)
Dennis
0

Un objeto es una colección de métodos y datos que tienen una alta cohesión. Pertenecen a una clase porque están altamente interrelacionados y se conserva el estado.

Esto es cierto ya sea que use un diseño inicial grande e intente modelar todo, o un diseño emergente en el que itera y evoluciona el objeto para adaptarlo a las necesidades del sistema en ese momento.

Si no tiene ninguna razón para retener el estado, probablemente no tenga ninguna razón para crear una instancia de un objeto, lo que significa que probablemente no haya razón para tener una clase. A menos que el lenguaje que está utilizando no tenga la capacidad de definir un espacio de nombres que no sea el uso de la clase. En el que usar clase debería estar bien porque sería idiomático.

No puedo pensar en ningún aspecto negativo para usar las clases de esta manera que no sea la típica. Su costo innecesario y su complejidad innecesarios al tener que crear una instancia de un "espacio de nombres". Cualquiera que respalde este código se preguntará dónde cuestan los datos una carga cognitiva adicional (muy probablemente un costo único por persona). Es un uso inusual sin ningún valor adicional.

dietbuddha
fuente