Os objetos no OOP precisam representar uma entidade?

82

Um objeto precisa representar uma entidade?

Por uma entidade que significa algo como um Product, Motor, um ParkingLotetc, um físico, ou mesmo um objecto não-físico conceptual clara - algo que está bem definida, com alguns dados básicos pertencem claramente ao objecto, e algumas funções / métodos que operam claramente nos dados principais.

Por exemplo, eu posso ter um objeto de a Demon, uma entidade em si, talvez imaginária e não física, mas uma entidade, no entanto

Um objeto pode ser apenas uma coleção de métodos , um conjunto comum de procedimentos vinculados a um objetivo comum?

Exemplo: uma classe pode ser chamada MotorOperationsou MotorActions, onde não há entidade, mas métodos dentro da classe fazem coisas como

  • getMotorDataFromHTMLForm ()
  • getMotorManufacturers ()
  • selectMotorFromUserRequirements ($ requirements)
  • canMotorCanHandleOperatingConditions ($ conditions)
  • computePowerConsumptionForMotor ($ id)

Uma classe é normalmente definida como dados centrais do objeto + operações nos dados. Portanto, para um Motor, pode haver algumas variáveis ​​de motor relacionadas às especificações do motor e pode haver operações que combinam esses dados para produzir alguma coisa.

No meu caso, é mais como se eu tivesse uma classe com operações em dados + dados que são passados ​​pela classe, não há dados centrados em "Operações Motoras", exceto dados temporários de passagem pela classe.

Pergunta, questão

As classes podem representar objetos sem entidade? Se não, por que eles são ruins / incompletos / não centrados no OOP? Existem maneiras pelas quais eles precisam ser alterados / aprimorados conceitualmente para estar alinhados com o POO?

Dennis
fonte
2
+1. Mas "sim" significaria que ele precisa representar uma entidade ou significaria que eles podem representar objetos sem entidade?
Panzercrisis 07/07
1
A primeira coisa que me vem à mente: java.awt e suas classes "Op" (por exemplo, docs.oracle.com/javase/7/docs/api/java/awt/image/… ), se é isso que você quer dizer. Representa uma operação. Agora, não tenho certeza se é uma boa prática (parece estranha e feia), mas está incluída na biblioteca padrão do Java, e o Java é OOP. Em geral.
Lucas
1
Não, não, mas isso não significa MotorActionsou MotorOperationssão boas idéias ou não.
precisa saber é o seguinte
1
Esta questão poderia se beneficiar de uma especificação adicional da lata .
Reinierpost
3
@ Dennis Eu realmente sinto que você está fazendo todas as perguntas erradas. Primeiro porque não há uma definição definitiva de POO, segundo porque os paradigmas são apenas um meio para atingir um fim. As únicas perguntas importantes são "escrever código dessa maneira facilita a discussão sobre sua correção?" e "escrever código dessa maneira facilita a reutilização?"
Doval

Respostas:

109

Não , um objeto não precisa representar uma entidade.

Na verdade, eu argumentaria que quando você para de pensar em objetos como entidades físicas é quando finalmente obtém os benefícios que o OOP promete.

Este não é o melhor exemplo, mas o design da Cafeteira é provavelmente o local onde a luz começou a acender para mim.

Objetos são sobre mensagens. Eles são sobre responsabilidades. Eles não são sobre carros, usuários ou pedidos.

Sei que ensinamos OO dessa maneira, mas depois de algumas tentativas, fica evidente como é fundamentalmente frustrante descobrir para onde as coisas vão quando você tenta fazer MVC, MVVM ou MVWhatever. Seus modelos ficam ridiculamente inchados ou seus controladores. Para a navegabilidade, é ótimo saber que tudo o que toca em Veículos está no arquivo Vehicle.ext, mas quando seu aplicativo é sobre Veículos, você inevitavelmente acaba com 3000 linhas de espaguete nesse arquivo.

Quando você tem uma nova mensagem para enviar, possui pelo menos um novo objeto e talvez um par deles. Portanto, na sua pergunta sobre um conjunto de métodos, eu argumentaria que você está potencialmente falando sobre um pacote de mensagens. E cada um pode ser seu próprio objeto, com seu próprio trabalho a fazer. E tudo bem. Ficará aparente à medida que você divide as coisas, que realmente precisam estar juntas. E você os junta. Mas você não coloca todos os métodos imediatamente em uma gaveta vagamente apropriada por conveniência, se quiser aproveitar o OO.

Vamos falar sobre bolsas de funções

Um objeto pode ser apenas uma coleção de métodos e ainda ser OO, mas minhas "regras" são bastante rígidas.

  1. A coleção deve ter uma única responsabilidade, e essa responsabilidade não pode ser tão genérica quanto "Faz coisas para os motores". Posso fazer uma fachada de camada de serviço, mas tenho plena consciência de que estou sendo preguiçoso por motivos de navegabilidade / descoberta, não porque estou tentando escrever código OO.

  2. Todos os métodos devem estar em uma camada consistente de abstração. Se um método recuperar objetos Motor e outro retornar Cavalos-força, isso provavelmente está muito distante.

  3. O objeto deve funcionar no mesmo "tipo" de dados. Esse objeto faz coisas com os motores (liga / desliga), este faz coisas com comprimentos de manivela, este lida com o seqüenciamento de ignição, este assume um formato html. Esses dados poderiam ser campos no objeto e pareceriam coesos.

Geralmente construo objetos desse tipo quando estou fazendo transformações, composições ou simplesmente não quero me preocupar com mutabilidade.

Acho que focar nas responsabilidades dos objetos me leva à coesão. Tem que haver alguma coesão para ser um objeto, mas não precisa haver campos nem muito comportamento para que seja um objeto. Se eu estivesse construindo um sistema que precisasse desses 5 métodos motores, começaria com 5 objetos diferentes que fazem essas coisas. Quando encontrei elementos comuns, começava a mesclar as coisas ou usava objetos "auxiliares" comuns. Isso me leva a preocupações abertas / fechadas - como posso extrair esse pouco de funcionalidade para nunca precisar modificar esse arquivo específico novamente, mas ainda usá-lo quando necessário?

Objetos são sobre mensagens

Os campos pouco importam para um objeto - obter e definir registros não muda o mundo fora do programa. A colaboração com outros objetos realiza o trabalho. No entanto, a força do OO é que podemos criar abstrações para não precisar pensar em todos os detalhes individuais de uma só vez. Abstrações que vazam ou não fazem sentido são problemáticas, por isso pensamos profundamente (talvez demais) sobre a criação de objetos que correspondem aos nossos modelos mentais.

Pergunta-chave: Por que esses dois objetos precisam se comunicar?

Pense no objeto como um órgão em uma pessoa - ele tem um objetivo padrão e só muda de comportamento quando recebe uma mensagem específica com a qual se importa.

Imagine um cenário em que você está na faixa de pedestres e um carro está chegando rápido. Como objeto cerebral, detecto um estressor. Eu digo ao hipotálamo para enviar hormônio liberador de corticotrofina. A hipófise recebe essa mensagem e libera hormônio corticotrófico adrenal. As glândulas supra-renais recebem essa mensagem e criam adrenalina. Quando o objeto muscular recebe essa mensagem de adrenalina, ele se contrai. Quando o coração recebe a mesma mensagem, ele bate mais rápido. Há toda uma cadeia de jogadores envolvidos no início do comportamento complexo de correr do outro lado da rua e são as mensagens que importam. O objeto do cérebro sabe como fazer com que o hipotálamo envie o alerta, mas não conhece a cadeia de objetos que eventualmente fará o comportamento acontecer. Da mesma forma, o coração não tem ideia de onde vem a adrenalina,

Portanto, neste exemplo ( simplificado ), o objeto da glândula adrenal precisa apenas saber como tomar ACTH e produzir adrenalina. Ele não precisa de campos para fazer isso, mas ainda parece um objeto para mim.

Agora, se nosso aplicativo for projetado apenas para correr do outro lado da rua, talvez eu não precise da glândula pituitária e dos objetos da glândula adrenal. Ou preciso apenas de um objeto da hipófise que faça apenas uma pequena parte do que conceitualmente podemos ver como o "modelo da hipófise". Todos esses conceitos existem como entidades conceituais, mas é um software e podemos criar o AdrenalineSender ou MuscleContractor ou qualquer outra coisa e não nos preocupar muito com a "incompletude" do nosso modelo.

Steve Jackson
fonte
4
Concordo com o conteúdo real desta resposta, mas sinto que ela não entende a pergunta. Especificamente, a questão inclui na entidade "ou um conceito, algo que está bem definido". Os contra-exemplos são " MotorOperationsou MotorActions". A partir disso, estou bastante confiante de que tanto os originais e projetos classe final do exemplo queda cafeteira na definição do OP de "representar uma entidade"
Ben Aaronson
1
A arquitetura de sistema pós-moderna DCI lida com isso sem as abstrações extremas criadas por engenheiros que amam estruturas. O computador deve pensar no que o usuário está pensando, e não o contrário. fulloo.info/doku.php?id=what_is_dci
ciscoheat
@BenAaronson Eu sinto que você pode evoluir para esse objeto como um conceito coeso, com esforço concertado suficiente, mas eu encontrei uma tendência para o foco de uma entidade forçar as coisas que deveriam ser separadas. As entidades incentivam limites em nossos nomes, o que é bom, mas também trazem essa noção de correção / perfeição, que tende a doer. Nos termos mais ridículos, sou a favor de um objeto FirstNameValidator e contra um objeto Name que também faz validação para nomes e sobrenomes.
Steve Jackson
2
Objetos são sobre mensagens - a resposta de Steve Jackson - isso é absolutamente certo. MOP não é o que se entende por "mensagem", como foi concebido pelo pai de OO Alan Kay, que disse que a grande idéia é mensagem . Além disso, desculpe-me por ter cunhado há muito tempo o termo "objetos" para este tópico, porque leva muitas pessoas a se concentrarem na idéia menor.
Radarbob
21

As classes podem representar objetos sem entidade? Se não, por que eles são ruins / incompletos / não centrados no OOP? Existem maneiras de mudar / melhorar?

Em resumo, você pode fazer qualquer coisa, mas esse cenário específico seria contrário aos princípios da OOP :)

O que você está descrevendo às vezes é chamado de classe "utilitário" - geralmente um sinal de cheiro de código. Você deseja evitar a criação de classes com o objetivo de manter alguns métodos juntos.

Nem todo objeto no seu aplicativo precisa estar vinculado a uma entidade da vida real, como um motor ou carro; esses são objetos de negócios. Em seu aplicativo, é provável que você use muitos de seus objetos de negócios, mas também precisará de mais segregação para outras operações que não fazem parte de entidades comerciais, como as listadas.

Você deve dar uma olhada nos padrões arquiteturais comuns - um deles é o MVC (Model-View-Controller) .

Se eu fosse distribuir os métodos listados usando o MVC, aqui está o que eu faria:

Ver classe:

  • GetMotorDataFromHTMLForm ()

Classe de modelo (motor essencial):

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

Classe de Controlador (MotorsController):

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

Parece que você está usando PHP; Uma boa estrutura MVC para se olhar é o Laravel . Em seus exemplos, eles ilustram bem a que métodos pertencem.

Outra fonte de informação mais genérica sobre como decidir aonde os métodos pertencem são os princípios GRASP e SOLID .

Alexus
fonte
obrigado. Em essência, parece-me que o que eu tenho é uma classe Controller com algumas impurezas misturadas (Model, View, etc). Isso quer dizer que, se eu mudar o nome MotorOperationspara MotorsControllere limpá-lo um pouco, minha coleção de funções será em linha com OOP?
217 Dennis
@ Dennis, não necessariamente, dê uma olhada na minha coleção de métodos em cada classe. O Controller não é uma classe que contém tudo :) É a classe que opera nos seus modelos e nada mais. As únicas dependências de um controlador geralmente seriam diretamente o DAL (Data Access Layer), ou serviços que fornecem acesso ao DAL. Você nunca deseja acessar o View do controlador (exemplo: getMotorDataFromHTMLForm); em vez disso, seu View deve ser aquele dependente do controlador.
Alexus
2
Você poderia explicar por que uma Utilsclasse seria um exemplo de cheiro de código? Apenas curioso, já que eu gostei de ter funções util aleatórias agrupadas em uma Utilsclasse em vez de apenas funções independentes ... na minha experiência, isso torna o código um pouco mais legível, mas minha experiência é limitada.
HC_ 07/07
3
@HC_ Ter uma classe Utils é o mesmo que ter uma pasta "Misc" na sua coleção de imagens. Indica que você estava com preguiça de atribuir responsabilidades aos seus objetos de maneira adequada / potencialmente ausente e usar Utils para compensar isso. Há um espaço para as classes Util, especialmente com funções estáticas e extensões para outras classes, mas antes de criar uma coleção como essa, verifique se você pode incorporá-las às suas classes OOP apropriadas :) Outro motivo é que às vezes uma classe só pode ter um método Mas daqui para frente, você precisa adicionar mais e a classe Utils se torna uma bagunça maior.
Alexus
Costumo terminar com uma BIBLIOTECA Utils, mas geralmente tento agrupar e nomear minhas classes utils um pouco mais descritivamente. Hoje em dia, existem muitas bibliotecas de "utilitários comuns" de código aberto por aí que já possuem utilitários de uso geral que a maioria das pessoas precisa, então eu procuraria um pouco antes de escrever sua própria.
Guy Schalnat
15

As classes podem representar objetos sem entidade?

Pode? Sim. Devemos? Provavelmente não - ou pelo menos não como você está expressando as coisas.

Na verdade, os objetos são melhores quando não representam um objeto físico diretamente, uma vez que a realidade é tão raramente mapeia bem o código. Mas eles precisam representar um conceito coeso ou objeto de código. Eles precisam representar uma única responsabilidade coesa.

Apenas agrupar várias funções tangencialmente relacionadas é um espaço para nome ou um módulo - não um objeto na linguagem OOP. Elas podem ser úteis, mas não são as mesmas, e exigem um tipo diferente de uso / pensamento para funcionar com eficácia.

Telastyn
fonte
3
bundling a bunch of tangentially related functions together is a namespace: isso soa mais como paradigma processual do que orientado a objetos.
217 Dennis
@ dennis - exatamente (ou funcional, se você o chamar de módulo). Misturar paradigmas pode ser poderoso. Ou pode ser terrivelmente bagunçado.
Telastyn 07/07/2015
Ou ambos :) - - - - -
Alexus
@Dennis: Ou nenhum dos dois - agrupar apenas funções relacionadas tangencialmente é uma prática dúbia em qualquer paradigma.
sdenham
Estou lidando com código que começou como uma base de código processual. Em algum momento, foi feito um esforço para convertê-lo em OOD, mas, na maioria das vezes, foram criadas classes para "reter funções e métodos", sem nenhum projeto real de OO. Tenho vindo a descobrir algumas coisas como esta que tentam preencher a lacuna entre paradigmas, mas não são nem de uma coisa nem outra
Dennis
11

Uma classe deve modelar algo - caso contrário, é inútil. No entanto, o que está sendo modelado pode não ser uma "coisa" física; em vez disso, pode ser uma representação de algo que não é 'real', mas que é necessário para controlar o sistema que está sendo modelado. Por exemplo, em um sistema de controle de semáforo, você poderia muito bem ter algum tipo de classe ControlSignal, representando um sinal enviado de uma parte do sistema para outra para indicar que alguma ação precisa ser executada. No "mundo real", esses sinais podem consistir em impulsos elétricos transmitidos pelos fios de uma caixa para outra. O processo de modelagem de algo que não é "real" como um objeto concreto é chamado de "reificação".

Boa sorte.

Bob Jarvis
fonte
Sim, isso é quase exatamente o que eu teria dito. Uma classe nada mais é do que um modelo para um substantivo . É isso aí. Nada mais nada menos. Uma classe é um substantivo e métodos são verbos (ou mensagens, se você preferir). Um engenheiro júnior que pensa nesses termos simples pode percorrer um longo caminho antes que essas analogias desapareçam (ao contrário de tentar fingir que as classes são descrições de objetos físicos - uma analogia que começa a desmoronar em quase seu primeiro projeto).
Calphool
7

Não. (Título editado para fazer a pergunta oposta!)

por exemplo:

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

ou

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

No entanto, em geral, o ideal por trás da OOP é afastar-se da

public struct Car
{
    public Wheel[] Wheels;
}

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

para

public class Car
{
    private Wheel[] wheels;
    Public int CountWheels()
    {
        return this.wheels.Length;
    }
}
Ewan
fonte
Você quer dizer que eles podem representar objetos sem entidade? (Veja o comentário que deixei sobre a questão.)
Panzercrisis
3
Acho que estou programando OO há muito tempo - quando olhei para o MyRepository, imediatamente imaginei uma tigela de vidro na minha cômoda com um monte de moedas e porcaria. Alcançar e agarrar um centavo, ou um botão ....
Bill K
@pan sim, como o serviço ea repo no meu exemplo
Ewan
@ Bill você louco velho tolo !!! Essa é a classe MyButtonAndOrPennyBowl! ftw de codificação limpa
Ewan
1
Seu segundo exemplo me parece uma função disfarçada de objeto, que não é (na minha opinião) justificada por si só, embora possa haver alguma outra justificativa (por exemplo, se funções não são entidades de primeira classe na linguagem. )
sdenham
5

Eu acho que visualizar algo no mundo real é útil ao codificar classes, mas não é necessário.

De fato, dependendo de como você quer ser literal, muitos objetos com os quais trabalhamos não têm representações físicas. Por exemplo - considere a arquitetura MVC. No mundo real, não há modelo ou controlador, mesmo que eles geralmente sejam representados por classes. Os três juntos geralmente representam algo, mas nem sempre - mas como eu disse, você provavelmente poderia forçar um encaixe em algo se você realmente quiser (e ser capaz de imaginar ALGO ajuda!) Visualizo a maioria dos objetos de alguma forma - apenas nada você veria no mundo real).

Na maioria das vezes, essas "Regras" que você aprenderá sobre OO são apenas diretrizes destinadas a orientá-lo a pensar em OO, não necessariamente em coisas com as quais você se preocupa muito depois de usá-lo para codificar diariamente.

A propósito, o OO em si não é uma panacéia e não ajuda muito em sua primeira passagem na codificação de alguma solução, mas acho que, se bem feito, é uma maneira verdadeiramente fantástica de organizar o código para que possa ser mais prontamente entendido mais tarde. Escrever código de manutenção é provavelmente uma das tarefas mais difíceis no desenvolvimento de software e, em muitos casos (qualquer coisa que exija depuração / manutenção contínua), é de longe a mais importante.

Bill K
fonte
5

Um objeto precisa representar uma entidade?

Pergunta: Qual entidade Loggerrepresenta?

Não metaforicamente - literalmente.

Ao explicar o POO aos alunos, é útil explicar objetos com analogias com o mundo físico.

Alan Kay - um dos pais da OOP - escreveu o seguinte:

[...]

A concepção original tinha as seguintes partes.

  • Pensei nos objetos como células biológicas e / ou computadores individuais em uma rede, capazes apenas de se comunicar com mensagens
  • Eu queria me livrar dos dados.

[...]

OOP para mim significa apenas mensagens, retenção e proteção local e

ocultação do processo estatal e extrema ligação tardia de todas as coisas.

arquitetura HW quase inacreditável. Eu percebi que o

a metáfora de célula / computador inteiro se livraria dos dados

fonte

A partir disso, os objetos são melhor entendidos como

  • objetos autárquicos que encapsulam / ocultam dados

  • comunicação com outros objetos via mensagens

As classes podem representar objetos sem entidade?

Definitivamente: pense em Math


Em relação ao seu exemplo:

Exemplo: uma classe pode ser chamada MotorOperations ou MotorActions, onde não há entidade, mas métodos dentro da classe fazem coisas como

  • getMotorDataFromHTMLForm ()

  • getMotorManufacturers ()

  • selectMotorFromUserRequirements ($ requirements)

  • canMotorCanHandleOperatingConditions ($ conditions)

  • computePowerConsumptionForMotor ($ id)

Para decidir onde colocar esses métodos, você deve dar uma olhada em responsibilities: quem é responsável por quê .

getMotorDataFromHTMLForm ()

O contexto desse método seria construir um objeto motor . Não é responsabilidade do motor criar-se a partir dos dados recuperados por meio de um formulário . Existem pelo menos dois objetos envolvidos; um é o motor e o outro é o criador do motor .

getMotorManufacturers ()

O contexto típico em que alguém escreveria esse método é a service.

selectMotorFromUserRequirements ($ requirements)

Isso também seria usado em um servicecontexto

canMotorCanHandleOperatingConditions ($ conditions)

Esta é uma pergunta para um motorobjeto

computePowerConsumptionForMotor ($ id)

Essa também é uma pergunta que deve ser feita ao próprio motor.


tl; dr

A metáfora de objectscomo objetos fisicamente é mais irritante do que útil.

Thomas Junk
fonte
uau, sua resposta dá vida ao POO! Eu tenho que dizer que eu não quis dizer físico como um fim para tudo. A intenção da minha pergunta era mais "um objeto precisa ser um thingdado com dados em que os dados claramente pertencem à coisa e funções que operam claramente nos dados que pertencem à coisa". Portanto, nesse caso, o Logger, embora não seja físico, é um conceito semelhante ao de um "diário de bordo físico". Se ele tem dados que é fundamental para seu estado, e não é apenas transitória a ele, que pode depender de aplicação e interpretação .. e é mais assim que a minha pergunta ia ..
Dennis
mas sim, respostas tiveram que enfrentar o meu físico viés
Dennis
3

Sim, você pode fazer isso. Mas você está essencialmente criando uma classe para fornecer a mesma funcionalidade de uma biblioteca de procedimentos. O único motivo para fazer isso é se sua linguagem não possui módulos procedimentais (por exemplo, Java ou Ruby).

Em uma linguagem com módulos procedurais (acho que o PHP possui módulos procedurais), você pode considerar usar apenas um módulo procedural.

Você também pode redesenhar sua classe para que uma instância da classe represente um objeto coerente.

Mas use apenas a notação OO quando estiver fornecendo energia extra, não apenas por ser OO!

Jonathan Cast
fonte
3

Nas palavras dos leigos

  • O que você descreve é ​​chamado de classe de utilitário.
  • Não tem estado, o que significa que você nunca precisará realmente ter várias instâncias
  • Todos os métodos são estáticos, o que significa que você deve passar tudo como parâmetros

Tais classes existem, por exemplo, o Java SDK possui a classe Collections, que consiste exclusivamente em métodos estáticos que operam ou retornam coleções.

Portanto, a resposta seria não, nem todas as classes precisam ser modeladas a partir de uma entidade de domínio.

Por outro lado, essas classes são poucas ou devem ser poucas em um programa feito em uma linguagem OOP, uma vez que o poder real da OOP reside no polimorfismo e no encapsulamento.

Seria como usar um avião para ir de um lugar para outro, não voando, mas dirigindo-o pelas estradas. Os aviões têm rodas como os carros, mas pretendem voar.

Tulains Córdova
fonte
2

Não, uma classe apenas representa algo que pode ser instanciado, tem membros e pode ser herdado.

De fato, seu idioma pode ter classes estáticas, que nem sequer são instanciadas mais de uma vez.

O .NETMath é um ótimo exemplo de uma classe "profissional" que não representa nenhuma entidade (a menos que você queira ser filosófico sobre o que é matemática ...) e também ilustra um caso de uso legítimo dessa classe. Possui apenas métodos e 2 campos (ambos representando constantes individuais).

A hierarquia de classes de uma biblioteca semelhante Math.Netagrupa métodos matemáticos / numéricos em classes por tipo. Aqui, as classes representam não uma entidade, mas uma categoria lógica.

Eu próprio frequentemente acabo criando classes (estáticas) que nada mais são do que um pacote de funções relacionadas (estáticas) ou um monte de constantes convenientemente agrupadas em um local central. Eu não diria que esse é um bom design, mas às vezes é a solução mais direta.

Superbest
fonte
1
O fato de os métodos relacionados à matemática serem colocados no .NET / BCL em uma classe separada como métodos estáticos não é uma necessidade ou consideração de design, mas uma consequência do fato de que não há métodos independentes em C #. No C ++, essas funções podem ser agrupadas em um espaço para nome.
Vlad
1

As respostas às suas perguntas dependem, em última análise, da precisão com que alguém define termos como "classe" e "entidade". Você fez um bom trabalho ao definir o último, permitindo entidades físicas e conceituais. Mas o termo "classe" para puristas sempre será "uma fábrica para instanciar objetos com uma representação interna específica" e, para pragmatistas, o termo abrangerá aquelas coisas em Java ou C ++ desprezadas pelos puristas. O mesmo vale para o termo "OOP", que os pragmáticos podem dizer que Java e C ++ fazem, mas quais puristas entenderiam o que Alan Kay quis dizer quando comentou ["Inventei o termo orientado a objetos e posso dizer que não tenha C ++ em mente "] ( Então, o que * Alan Kay realmente quis dizer com o termo" orientado a objetos "? ).

Se você adotar a visão pragmatista, poderá aceitar suas classes de utilitário sem instância. Mas a visão purista é mais interessante. OPA, de acordo com Kay, sempre foi mais sobre as mensagens do que sobre as aulas. Então, para suas perguntas:

As classes podem representar objetos sem entidade?

Não. Classes classificam objetos. As classes são, por definição, aquelas entidades para as quais você envia uma mensagem, como newpara produzir um objeto. Um objeto é uma entidade criada a partir de uma classe. Existem classes para fabricar, e realmente classificar, objetos. É isso que as aulas fazem. Classes criam objetos. Usamos classes para classificar objetos. Portanto, se C é apenas um conjunto de métodos que não permite instanciação ou subclasse, não pode haver objetos classificados por C, portanto, C não é uma classe.

Se não, por que eles são ruins / incompletos / não centrados no OOP?

Eles não são ruins. Só não os chame de aulas. Um pacote de métodos é OOPable: algo para o qual você pode enviar uma mensagem para chamar um método, mas não é uma classe, a menos que possa instanciar um objeto. Você conhece Ruby? No Ruby, um módulo é um pacote de métodos. Uma classe é um módulo que pode instanciar objetos. Não há nada de ruim em um módulo . Mas o que diferencia uma classe de um módulo (em termos puros de OOP) é ​​que uma classe pode ter instâncias. Um módulo é apenas alguns métodos. A confusão é que C ++, Java e outras linguagens usam o termo "classe" para classe e módulo .

Agora, para examinar um de seus exemplos específicos, você pergunta sobre uma MotorOperationsclasse para a qual você pode enviar a mensagem computePowerConsumptionForMotorcom argumento id. Isso é ruim? Pelo menos, não viola o princípio Tell Don't Ask . Temos que fazer uma aula de motor e enviar a powerConsumptionmensagem? Talvez não 100% do tempo, mas talvez tentar fazer isso levará a algumas informações interessantes sobre o seu código. Ou pode levar a uma explosão de turmas que seriam ruins.

Existem maneiras pelas quais eles precisam ser alterados / aprimorados conceitualmente para estar alinhados com o POO?

Se "fazer OOP" for importante para você, você precisará procurar maneiras de arquitetar um sistema em componentes que se comunicam enviando mensagens um para o outro. Isso é exatamente o que é POO , ou pelo menos o que o criador do termo tinha em mente. As classes de utilitário não são OOP nessa exibição. Mas para algumas pessoas, podem ser.

Tentar transformar todo um sistema amplo em milhões de objetos vivos, respiratórios, todos instanciados nas aulas, pode funcionar em alguns projetos. Mas se você estiver criando classes artificiais e com som errado, então os módulos devem ser introduzidos. Tente enfatizar as classes e use módulos quando as classes instáveis ​​forem ridículas.

TL; DR - pacotes de métodos nem sempre são ruins. Tente usar classes instáveis ​​primeiro. Retorne aos "módulos" somente quando necessário.

Ray Toal
fonte
0

Tomando os exemplos dados:

getMotorDataFromHTMLForm()
selectMotorFromUserRequirements($requirements)

Eles se parecem com métodos "de fábrica", que retornariam um Motorobjeto. O segundo implica que você está criando um novo objeto para atender aos requisitos ou possui um banco de dados ou uma coleção de motores na memória que está examinando. Nesse caso, deve ser um método para isso. Ou poderia ser um método no objeto de requisitos.

getMotorManufacturers()

De onde você os está pegando? É para isso que deve ser um método.

canMotorCanHandleOperatingConditions($conditions)
computePowerConsumptionForMotor($id)

Parece que eles devem ser métodos Motor.

pjc50
fonte
Sim. é um "pacote de métodos possivelmente não relacionados" (BOPUM, para abreviar). Eu concordo com os comentários da fábrica e do motor. getMotorManufacturersé retornar todos os fabricantes de motores do banco de dados. Não sei para onde isso vai. Ele vai me levar algum tempo para desvendar esse BOPUM para colocar as coisas onde eles precisam ir ..
Dennis
Estou recebendo getMotorManufacturersdo banco de dados. O banco de dados não pode ter um método ... Atualmente, tenho um padrão DataMapper que consulta o banco de dados, inicializa uma matriz e a preenche com Objetos Motorizados (também contendo informações do Fabricante) e, em seguida, retorna essa matriz ao chamador. O chamador é minha MotorOperationsclasse, que por sua vez é chamada a partir de uma ProductSelectionclasse (que contém um algoritmo que é usado para seleccionar Motors, e informação sobre o motor é carregado os dados para que o algoritmo)
Dennis
0

Um objeto é uma coleção de métodos e dados com alta coesão. Eles pertencem a uma classe porque são altamente inter-relacionados e o estado é retido.

Isso é verdade se você usa um grande projeto inicial e tenta modelar tudo, ou um design emergente, onde itera e evolui o objeto para o que se adapta às necessidades do sistema no momento.

Se você não tiver motivos para reter o estado, provavelmente não terá motivos para instanciar um objeto, o que significa que provavelmente não há motivos para ter uma classe. A menos que o idioma que você está usando não tenha a capacidade de definir um espaço para nome que não seja a classe. Em que o uso de classe deve ser bom, porque seria idiomático.

Não consigo pensar em nenhum aspecto negativo do uso de classes dessa maneira, além do típico. Você está convidando custos e complexidade desnecessários ao instanciar um "espaço para nome". Qualquer pessoa que suporte esse código se perguntará onde os dados estão custando carga cognitiva adicional (provavelmente um custo único por pessoa). É um uso incomum, sem nenhum valor adicional.

dietbuddha
fonte