85

Does an object have to represent an entity?

By an entity I mean something like a Product, Motor, a ParkingLot etc, a physical, or even a clear-cut non-physical conceptual object -- something that is well defined, with some core data clearly belonging to the object, and some functions/methods that clearly operate on the core data.

For example, I can have an object of a Demon, an entity in itself, an imaginary one perhaps and not physical but an entity nevertheless

Can an object be just a collection of methods, a common set of procedures that tie in with a common goal?

Example: can a class be called MotorOperations or MotorActions, where there is no entity, but methods inside the class do things like

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

A class is typically defined as data central to the object + operations on data. So for a Motor there may be some motor variables relating to motor specifications, and there can be operations that combine those data to produce something.

In my case it is more like I have a class with operations on data + data that is passed through the class, there is no data centric to "Motor Operations", other than temporary pass-through-the-class data.

Question

Can classes represent entity-less objects? If not, why they are bad/incomplete/non-OOP-centric? Are there ways they need to be changed/improved conceptually to be in line with OOP?

Dennis
  • 8,157
  • 5
  • 36
  • 68
  • 2
    +1. But would "yes" mean that it does have to represent an entity, or would it mean that they can represent entity-less objects? – Panzercrisis Jul 07 '15 at 21:29
  • 1
    First thing that comes to my mind: java.awt and its "Op" classes (e.g.http://docs.oracle.com/javase/7/docs/api/java/awt/image/ConvolveOp.html), if that's what you mean. It represents an operation. Now, I'm not sure whether it's good practice (it does look weird and ugly), but it's included in Java standard library, and Java is OOP. For the most part. – Luke Jul 07 '15 at 21:49
  • 1
    No it doesn't, but that doesn't mean `MotorActions` or `MotorOperations` are good ideas or not. – user253751 Jul 08 '15 at 09:26
  • @Luke : Are these "Op" classes just a workaround for functions not being first-class entities? – sdenham Jul 08 '15 at 13:32
  • I don't think the example is very helpful - there seems to be a concrete object here ('motor'), raising the question as to whether these would be better as methods for a motor class. – sdenham Jul 08 '15 at 13:43
  • 1
    This question could benefit from a further specification of *can*. – reinierpost Jul 08 '15 at 16:47
  • @reinier, I will have to think about that, but in essence, some questions that may clarify, or muddy things up -- do there exist proper OOP objects that contain only methods, without data (any data is strictly transient). Are object without data but only methods possible? Is such a thing even called an object? Can there be a pure intended OOP entities with bundles of methods, without the need to be untangled into separate different entities to achieve proper OOP entity composition? – Dennis Jul 08 '15 at 18:25
  • I guess by "can" i mean something where seasoned developers will not recommend breaking the object into separate entities. aka, the object will be whole, unbroken, as defined, as intended by OOP principles, without the need to be altered. By can I mean "can such object exist (without the threat of decomposition or alteration)". – Dennis Jul 08 '15 at 18:36
  • 3
    @Dennis I really feel like you're asking all the wrong questions. First because there's no one definitive definition of OOP, second because paradigms are only a means to an end. The only questions that matter are "does writing code this way make it easier to reason about its correctness?" and "does writing code this way make it easier to reuse?" – Doval Jul 08 '15 at 18:38
  • @Dennis Whether an object "contains" a kind of data or just "modifies" a specific kind of data is an implementation detail. You can do OO without classes, without inheritance, and without member variables. The core idea for me is that these things (data and behavior) go together and can be encapsulated = object. The "problem" with generic bags of behavior is that they generally have too many responsibilities to be considered a cohesive object. – Steve Jackson Jul 08 '15 at 23:22
  • Your examples are essentially what service and repository layers are in enterprise applications. A repository simply passes data between the business service layer and the database, which are usually a variety of different entities. Your service contains all of your business logic, and passes the results up to your view logic. And then your view logic does what it needs to do present the required information. – Ellesedil Jul 09 '15 at 18:16
  • This is a common pattern (see [Arrays](http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html), [Collections](http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html)) and it is considered useful. It just isn't particularly OO. – Kevin Krumwiede Jul 09 '15 at 22:32
  • A class authorizes an entity, otherwise multiple classes could be assigned to the same name. – toplel32 Jul 13 '15 at 18:03
  • There are different kinds of objects. Entities can be objects, but so can values (if your language doesn't have value types - e.g. strings and dates in Java) and software components (like webservers). – user253751 Mar 27 '17 at 23:15

14 Answers14

113

No, an object does not have to represent an entity.

In fact, I would argue that when you stop thinking about objects as physical entities is when you finally get the benefits that OOP promises.

This isn't the best example, but the Coffee Maker design is probably where the light started to come on for me.

Objects are about messages. They're about responsibilities. They're not about Cars, Users, or Orders.

I know we teach OO this way, but it becomes apparent after a few tries how fundamentally frustrating it is to figure out where things go when you try to do MVC, MVVM or MVWhatever. Either your models become ridiculously bloated or your controllers do. For navigability, it's great to know that anything that touches Vehicles is in the Vehicle.ext file, but when your application is about Vehicles, you inevitably end up with 3000 lines of spaghetti in that file.

When you have a new message to send, you have at least one new object, and perhaps a pair of them. So in your question about a bundle of methods, I would argue that you're potentially talking about a bundle of messages. And each one could be its own object, with it's own job to do. And that's ok. It will become apparent as you split things apart which things really, really need to be together. And you put them together. But you don't immediately drop every method in a vaguely appropriate drawer for convenience sake if you want to enjoy OO.

Let's talk about bags of functions

An object can be just a collection of methods and still be OO, but my "rules" are pretty strict.

  1. The collection should have a single responsibility, and that responsibility can't be as generic as "Does stuff to motors". I might do such a thing as a service-layer facade, but I'm acutely aware that I'm being lazy for navigability/discovery reasons, not because I'm trying to write OO code.

  2. All the methods should be at a consistent layer of abstraction. If one method retrieves Motor objects and another returns Horsepower, that's probably too far apart.

  3. The object should work on the same "kind" of data. This object does stuff to motors(start/stop), this one does things with crank lengths, this one handles ignition sequencing, this one takes an html form. This data could conceivably be fields on the object and it would seem cohesive.

I generally build objects of this sort when I'm doing transforms, composition, or just don't want to worry about mutability.

I find focusing on object responsibilities leads me towards cohesion. There has to be some cohesion to be an object, but there doesn't need to be any fields nor very much behavior for it to be an object. If I was building a system that needed those 5 motor methods, I would start out with 5 different objects that do those things. As I found commonality, I would either start to merge things together or use common "helper" objects. That moves me into open/closed concerns - how can I extract this bit of functionality so I never have to modify that particular file again but still use it where needed?

Objects are about messages

Fields barely matter to an object - getting and setting registers doesn't change the world outside the program. Collaborating with other objects gets the work done. However, the strength of OO is that we can create abstractions so we don't have to think about all the individual details at once. Abstractions that leak or don't make sense are problematic, so we think deeply (too much, maybe) about creating objects that match our mental models.

Key question: Why do these two objects need to talk to each other?

Think of the object as an organ in a person - it has a default purpose and only changes behavior when it receives a specific message that it cares about.

Imagine a scenario where you're in the crosswalk and a car is coming fast. As the brain object, I detect a stressor. I tell the hypothalamus to send corticotrophin-releasing hormone. The pituitary gland gets that message and releases adrenal corticotrophic hormone. The adrenal glands get that message and create adrenaline. When the muscle object gets that adrenaline message it contracts. When the heart get the same message, it beats faster. There's a whole chain of players involved in starting the complex behavior of sprinting across the street and it's the messages that matter. The brain object knows how to get the hypothalamus to send out the alert, but it doesn't know the chain of objects that will eventually make the behavior happen. Likewise the heart has no idea where adrenaline comes from, it just knows to do something different when that shows up.

So in this (simplified) example, the adrenal gland object only needs to know how to take ACTH and make adrenaline. It doesn't need any fields to do that, yet it still seems like an object to me.

Now if our application is designed only to sprint across the street, I may not need the pituitary gland and the adrenal gland objects. Or I only need a pituitary gland object that only does a small part of what we might conceptually see as the "pituitary gland model". These concepts all exist as conceptual entities, but it's software and we can make the AdrenalineSender or MuscleContractor or whatever and not worry much about the "incompleteness" of our model.

Steve Chamaillard
  • 1,691
  • 1
  • 11
  • 20
Steve Jackson
  • 3,595
  • 1
  • 20
  • 27
  • 4
    I agree with the actual content of this answer, but I feel like it misunderstands the question. Specifically, the question includes in entity "or a concept, something that is well defined". Counter-examples to this are "`MotorOperations` or `MotorActions`". From this, I'm pretty confident that both the original **and** final class designs from the CoffeeMaker example fall under the OP's definition of "representing an entity" – Ben Aaronson Jul 08 '15 at 12:37
  • 1
    The postmodern system architecture DCI handles this without the extreme abstractions created by structure-loving engineers. The computer *should* think what the user is thinking, not the other way around. http://fulloo.info/doku.php?id=what_is_dci – ciscoheat Jul 08 '15 at 15:29
  • @BenAaronson I feel like you can evolve to that object as cohesive concept with enough concerted effort, but I have found a tendency for an entity-focus to force things together that should be apart. Entities encourage boundaries in our names, which is good, but they also bring along this notion of correctness/completeness, which tends to hurt. In the most ridiculous terms, I'm for a FirstNameValidator object and against a Name object that also does validation for first and last names. – Steve Jackson Jul 08 '15 at 17:03
  • 1
    Another good example: http://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/ – Moby Disk Jul 08 '15 at 19:09
  • Doesn't it make more sense to have them as functions in a file, instead of abstract classes? – Jeroen Jul 09 '15 at 13:28
  • Good answer, however do not start going too far down the idea of passing messages. Message Oriented Programming (MOP) is quite different to OOP. The problem most people have is the first examples are always concrete things like cars have wheels as do bikes, both are vehicles and can move. The more useful things to many are the abstract; factory classes make other ones, manager classes are aware of their children, all classes have a stringify for their data. – TafT Jul 10 '15 at 07:46
  • 2
    _Objects are about messages_ - Steve Jackson's answer - this is absolutely right on. MOP is not what is meant by "messaging" as conceived by The Father of OO [Alan Kay](https://en.wikipedia.org/wiki/Alan_Kay) who said [_the big idea is messaging_](http://www.c2.com/cgi/wiki?AlanKayOnMessaging). And further, _I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea._ – radarbob Jul 11 '15 at 22:32
  • Nice perspective on OOP – Jason P Sallinger Jul 13 '15 at 16:52
  • "Objects are about Messages" - do you mean simply that I should put my focus on a communication between the two necessary entities that the message must travel to and from when I think about how to design my code? – Dennis Jul 15 '15 at 16:17
  • @Dennis - yes communication between objects is a good place to focus. Sometimes I prefer to start from the responsibility angle, but they tend to lead toward the same place. To steal from Twain “I didn't have time to write a short comment, so I added to the answer instead.” – Steve Jackson Jul 16 '15 at 02:11
  • _, I'm for a FirstNameValidator object and against a Name object that also does validation for first and last names._ I'm for a Name object that validates its first name using the FirstNameValidator. If FirstNameValidation is needed in non-Name classes, sure encapsulate that if instantiating a Name each time does not make sense in the domain. – radarbob Sep 15 '15 at 15:02
  • Coffee maker link is dead – Adam B Feb 22 '22 at 19:35
21

Can classes represent entity-less objects? If not, why they are bad/incomplete/non-OOP-centric? Are there ways they need to be changed/improved?

In short, you can do anything, but this specific scenario would be against OOP principles :)

What you are describing is sometimes called a "utility" class - usually a sign of code smell. You want to avoid creating classes for the sake of keeping some methods together.

Not every object in your application has to be linked to a real-life entity like a motor, or car; those are business objects. In your application, you are likely to use many of your business objects, but you would also need some more segregation for other operations that are not part of business entities, like the ones you listed.

You should have a look at common architectural patterns - one of them is MVC (Model-View-Controller).

If I was to distribute the methods you listed using MVC, here is what I would do:

View Class:

  • GetMotorDataFromHTMLForm()

Model Class (Motor Essentially):

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

Controller Class(MotorsController):

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

It seems like you are using PHP; a good MVC framework to have a look at is Laravel. In their examples they illustrate well where what methods belong to.

Another, more generic source of information how to decide where the methods belong are GRASP and SOLID principles.

Peter Mortensen
  • 1,050
  • 2
  • 12
  • 14
Alexus
  • 2,368
  • 15
  • 24
  • thanks. In essence, it looks to me that what I have is a Controller class with a few impurities mixed in (Model, View, etc). Does that mean that if I rename `MotorOperations` to `MotorsController` and clean it up a bit, my *collection of functions* will be in line with OOP? – Dennis Jul 07 '15 at 22:25
  • @Dennis, Not necessarily, have a look at my collection of methods under each class. Controller is not a class that contains it all :) It's the class that has operation on your models, and nothing more. The only dependencies of a controller would generally be DAL(Data Access Layer) directly, or services that provide you access to DAL. You never want to access View from the controller (example: getMotorDataFromHTMLForm), instead, your View should be the one dependent on the controller. – Alexus Jul 07 '15 at 23:00
  • 2
    Could you elaborate on why a `Utils` class would be an example of code smell? Just curious, as I have myself enjoyed having random util functions wrapped in a `Utils` class as opposed to just being stand-alone functions... in my experience it makes code a bit more readable, but my experience is limited. – HC_ Jul 07 '15 at 23:45
  • 3
    @HC_ Having a Utils class is the same as having a "Misc" folder in your picture collection. It indicates that you were lazy to assign responsibilities to your objects properly/potentially missing objects and use Utils to compensate for that. There is a room for Util classes, especially with static functions, and extensions to other classes, but before you create a collection like that, check if you can incorporate them into your proper OOP classes :) Another reason is sometimes a class can only have one method. But going forward, you need to add more and Utils class becomes a bigger mess. – Alexus Jul 08 '15 at 00:19
  • I often end up with a Utils LIBRARY, but I usually try to group and name my utils classes a bit more descriptively. These days, there are many open source "common utilities" libraries out there that already have general purpose utilities that most people need, so I'd look around a bit before writing your own. – Guy Schalnat Jul 09 '15 at 17:02
  • @GuySchalnat I haven't had to create a "utility" class in 4 years now. It all comes nicely together and aligns into classes upon refactoring phase :) – Alexus Jul 09 '15 at 17:20
  • Wow, I wouldn't design a MVC application like this. This is fine as a simple example for MVC, but if you're going to design anything that resembles an enterprise web application using MVC, you'll want your M, V, and C to only worry about view logic, your business layer in a business service class, and an repository layer devoid of business logic to be the interface between your business service and your database. The service and repo classes will concern themselves with data access and processing, your controller (C) will set up your viewmodels (M), and then return your views (V). – Ellesedil Jul 09 '15 at 18:11
  • @Ellesedil That is obvious to senior developers familiar with the pattern, but for the purpose of answering the question, we first need to somewhat distribute responsibilities. Definitely for enterprise-size app you would want to gain some experience before even getting into it. – Alexus Jul 09 '15 at 18:32
  • Then I guess I don't understand the answer. Your service and repo layers will be classes that do not represent entities, but instead pass all sorts of different entities up and down other layers or otherwise transform them. So, we'd have an AutomobileRepo which will GetMotor and GetParkingLot, an AutomobileService will call GetMotor and other components to put a Car entity together, and then determine which ParkingLot entity to get from the repo that the Car should be in. That sounds exactly what the question is asking about. – Ellesedil Jul 09 '15 at 18:37
  • @Ellesedil I am confused as to what you are referring to? All I did is merely restructured the groupings of methods that OP provided with some hint on roper OOP techniques. If I was to design this system, I would need more information than provided in the question. – Alexus Jul 09 '15 at 19:48
15

Can classes represent entity-less objects?

Can? Yes. Should? Probably not - or at least, not how you're phrasing things.

Objects actually are best when not representing a physical object directly since reality so infrequently maps nicely to code. But they do need to represent a cohesive concept or code-object. They need to represent a single cohesive responsibility.

Just bundling a bunch of tangentially related functions together is a namespace or a module - not an object in OOP parlance. Those can be useful, but they're not the same, and require a different sort of usage/thinking to work with effectively.

Telastyn
  • 108,850
  • 29
  • 239
  • 365
  • 3
    `bundling a bunch of tangentially related functions together is a namespace`: that sounds more like procedural paradigm rather than object oriented. – Dennis Jul 07 '15 at 20:42
  • @dennis - exactly (or functional if you call it a Module). Mixing paradigms can be powerful. Or it can be terribly messy. – Telastyn Jul 07 '15 at 20:43
  • Or both :) - - - - - – Alexus Jul 07 '15 at 20:59
  • @Dennis : Or neither - bundling together only tangentially related functions is a dubious practice in any paradigm. – sdenham Jul 08 '15 at 14:55
  • I am dealing with code that started out as a procedural codebase. At some point an effort to convert it to OOD was made but, mostly classes were created to "hold functions and methods", without any actual OO-design. I have been discovering quite a few things like this that try to bridge the gap between paradigms but are neither in one nor the other – Dennis Jul 08 '15 at 15:03
  • @Dennis: If one needs a method which, given values `x` and `y`, computes √(x²+y²), there may occasionally be benefit to having a `DistanceCalculator` object (especially if many (x,y) pairs will get repeated, and one is on a system where floating-point math is particularly slow) but if the desired behavior is defined by something which is immutable and outside the universe the program is modeling (e.g. the mathematical works of Pythagoras) trying to coerce it into an OOP model is counterproductive. – supercat Jul 08 '15 at 18:55
11

A class should model something - otherwise it's pointless. However, what's being modeled may not be a physical "thing"; instead, it may be a representation of something which is not 'real', but which is needed to control the system being modeled. For example, in a traffic light control system you could very well have some sort of ControlSignal class, representing a signal sent from one portion of the system to another to indicate that some action needs to be performed. In "the real world" these signals might consist of electrical impulses transmitted across wires from one box to another. The process of modeling something which isn't "real" as a concrete object is referred to as "reification".

Best of luck.

  • Yep, that's almost precisely what I would have said. A class is nothing more than a model for a *noun*. That's it. Nothing more, nothing less. A class is a noun, and methods are verbs (or messages if you prefer). A junior engineer who thinks in those simple terms can go a *long* way before those analogies break down (unlike trying to pretend that classes are descriptions of physical objects -- an analogy that starts to break down on almost your first project). – Calphool Jul 09 '15 at 21:05
7

No. (Title edited to ask the opposite question!)

eg:

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

or

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

However, in general the ideal behind OOP is to move away from

public struct Car
{
    public Wheel[] Wheels;
}

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

to

public class Car
{
    private Wheel[] wheels;
    Public int CountWheels()
    {
        return this.wheels.Length;
    }
}
Ewan
  • 70,664
  • 5
  • 76
  • 161
  • Do you mean that they can represent entity-less objects? (See the comment I left on the question.) – Panzercrisis Jul 07 '15 at 21:31
  • 3
    I've been programming OO too long I guess--when I looked at MyRepository I immediately pictured a glass bowl on my dresser with a bunch of coins and crap in it. Reach in and grab out a penny, or a button.... – Bill K Jul 07 '15 at 22:58
  • @pan yes, like the service and the repo in my example – Ewan Jul 08 '15 at 05:36
  • @bill you crazy old fool!!! Thats the MyButtonAndOrPennyBowl class! clean coding ftw – Ewan Jul 08 '15 at 05:37
  • 1
    Your second example looks to me like a function dressed up as an object, which is not (in my opinion) justified for its own sake, though there may be some other justification (e.g. if functions are not first-class entities in the language.) – sdenham Jul 08 '15 at 14:10
  • The Service? Yes I guess it is. However, an actual service would have state and dependencies as well, db connections or authentication of the request etc – Ewan Jul 09 '15 at 06:25
5

I think that visualizing something in the real world is helpful when coding classes but not necessary.

In fact, depending on how literal you want to be, many objects we work with don't have physical representations at all. For instance--consider MVC architecture. In the real world there is no Model or Controller even though they are generally represented by classes. The three together often represent something, but not always--but as I said you could probably force a fit into something if you really want to (and being able to imagine SOMETHING helps! I visualize most objects in some way--just not anything you'd ever see in the real world).

Mostly these "Rules" you will learn about OO are just guidelines meant to get you oriented into thinking in OO not necessarily things you worry about much once you are using it to code on a daily basis.

By the way OO itself isn't some panacea and it doesn't help you much at all during your first pass at coding some solution, but I think that if done right it is a truly fantastic way to organize code so it can be more readily understood later. Writing maintainable code is probably one of the hardest tasks in software development and in many cases (anything that requires ongoing debugging/maintenance) it is by far the most important.

Bill K
  • 2,699
  • 18
  • 18
5

Does an object have to represent an entity?

Question: Which entity does a Logger represent?

Not metaphorically - literally.

When explaining OOP to students it is helpful to explain objects with analogies to the physical world.

Alan Kay - one of the fathers of OOP - wrote the following:

[...]

The original conception of it had the following parts.

  • I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages
  • I wanted to get rid of data.

[...]

OOP to me means only messaging, local retention and protection and

hiding of state-process, and extreme late-binding of all things.

almost unbelievable HW architecture. I realized that the

cell/whole-computer metaphor would get rid of data

source

From this, objects are best understood as

  • autarkic objects encapsulating / hiding data

  • communicating with other objects via messages

Can classes represent entity-less objects?

Definitely: Think of Math


Regarding your example:

Example: can a class be called MotorOperations or MotorActions, where there is no entity, but methods inside the class do things like

  • getMotorDataFromHTMLForm()

  • getMotorManufacturers()

  • selectMotorFromUserRequirements($requirements)

  • canMotorCanHandleOperatingConditions($conditions)

  • computePowerConsumptionForMotor($id)

To decide, where to put these methods, you have to take a look at responsibilities: who is respnsible for what.

getMotorDataFromHTMLForm()

The context of such a method would be constructing a motor-object. It is not the responsibility of the motor to create itself from Data retrieved via a form. There are at least two objects involved; one is the motor and the other is the creator of the motor.

getMotorManufacturers()

The typical context in which one would write such a method is a service.

selectMotorFromUserRequirements($requirements)

This would also be used in a service-context

canMotorCanHandleOperatingConditions($conditions)

This is a question to a motor-object

computePowerConsumptionForMotor($id)

This too is a question best asked a motor itself.


tl;dr

The metaphor of objects as physically objects is more irritating than helpful.

Thomas Junk
  • 9,405
  • 2
  • 22
  • 45
  • wow your answer breathes some life into OOP! I have to say that I didn't mean *physical* as an end to it all. intent of my question was more "does an object have to be a `thing` with data where data clearly belongs to the thing and functions that clearly operate on the data that belongs to the thing". So Logger in this case, while not a physical thing, it is a concept akin to that of a "physical log book". Whether it has data that is core to its state, and is not just transient to it, that may depend on implementation and interpretation .. and is more so where my question was going.. – Dennis Jul 08 '15 at 18:06
  • but yes, answers had to address my *physical* bias – Dennis Jul 08 '15 at 18:26
3

Yes, you can do this. But you're essentially creating a class to provide the same functionality as a procedural library. The only reason to do that is if your language lacks procedural modules (e.g., Java or Ruby).

In a language with procedural modules (I think PHP has procedural modules), you might consider just using a procedural module.

You could also consider re-designing your class so an instance of the class represents a coherent object.

But only use OO notation when it's giving you extra power, not just for the sake of being OO!

Jonathan Cast
  • 217
  • 3
  • 10
3

In layman's words

  • What you describe is called an utility class.
  • It has no state, meaning you will not ever really need to have several instances of it
  • All methods are static, meaning you have to pass everything as parameters

Such classes do exist, for example the Java SDK has the Collections class which consists exclusively of static methods that operate on or return collections.

So the answer would be no, not all classes need to be modelled from a domain entity.

In the other hand, such classes are only a few or should be only a few in a program made in a OOP language, since the real power of OOP lays in polymorphism and encapsulation.

It would be like using a plane to go from one place to another not by flying but by driving it around on freeways. Planes have wheels like cars do, but they are intended to fly.

Tulains Córdova
  • 39,201
  • 12
  • 97
  • 154
2

No, a class merely represents something that can be instantiated, has members, and can be inherited from.

In fact, your language may have static classes, which are not even instantiated more than once.

.NET's Math is a great example of a "professional" class that represent no entity (unless you want to get philosophical about what math is...), and also happens to illustrate a legitimate use case of such a class. It has only methods and 2 fields (both representing individual constants).

The class hierarchy of a similar library, Math.Net, groups mathematical/numerical methods into classes by type. Here classes represent not an entity, but a logical category.

I myself often end up creating (static) classes which are nothing more than a bag of related (static) functions, or a bunch of constants conveniently grouped in one central place. I wouldn't claim that this is good design, but sometimes it's the most straightforward solution.

Superbest
  • 538
  • 1
  • 3
  • 12
  • 1
    The fact that the math-related methods are placed in .NET/BCL into a separate class as static methods is not a necessity or design consideration but a consequence of a fact that there are no free-standing methods in C#. In C++ such functions could be just grouped into a namespace. – Vlad Jul 13 '15 at 20:41
1

The answers to your questions ultimately hinge on how precisely one defines terms like "class" and "entity." You did a good job of defining the latter, allowing both physical and conceptual entities. But the term "class" to purists will always be "a factory for instantiating objects with a particular internal representation" and to pragmatists the term will encompass those Java or C++ things despised by purists. Ditto for the term "OOP," which pragmatists might say Java and C++ do, but which purists would take to mean what Alan Kay meant when he remarked ["I invented the term object-oriented, and I can tell you I didn't have C++ in mind"]( So what *did* Alan Kay really mean by the term "object-oriented"?).

If you take the pragmatist view, you can accept your instance-less utility classes. But the purist view is more interesting. OOP, according to Kay, was always more about the messages than the classes. So to your questions:

Can classes represent entity-less objects?

No. Classes classify objects. Classes are by definition those entities to which you send a message such as new to produce an object. An object is an entity made from a class. Classes exist to manufacture, and indeed classify, objects. That's what classes do. Classes make objects. We use classes to classify objects. So if C is just a bundle of methods that does not permit instantiation or subclassing, there cannot be any objects classified by C, so C is not a class.

If not, why they are bad/incomplete/non-OOP-centric?

They're not bad. Just don't call them classes. A bundle of methods is OOPable: something you could send a message to in order to invoke a method, but it's not a class unless it can instantiate an object. Do you know Ruby? In Ruby a module is a bundle of methods. A class is a module that can instantiate objects. There is nothing bad about a module. But the thing that makes a class different from a module (in pure OOP terms) is that a class can have instances. A module is just some methods. The confusion is that C++ and Java and other languages use the term "class" for both class and module.

Now, to look at one of your specific examples, you ask about a MotorOperations class to which you could send the message computePowerConsumptionForMotor with argument id. Is that bad? At least it does not violate the Tell Don't Ask Principle. Do we have to make a motor class and send it the powerConsumption message? Maybe not 100% of the time, but maybe trying to do such things will lead to some nice insights about your code. Or, it can lead to an explosion of little classes which would be bad.

Are there ways they need to be changed/improved conceptually to be in line with OOP?

If "doing OOP" is important to you, then you will want to look for ways to architect a system into components that communicate by sending messages to each other. That is just what OOP is, or at least what the coiner of the term had in mind. Utility classes are not OOP in this view. But to some people, they may be.

Trying to make an entire large system out of millions of living, breathing, objects, all instantiated from classes, may work for some projects. But if you find yourself creating artificial, wrong-sounding classes, then modules should be introduced. Try to emphasize classes, and use modules when instantiable classes would be ridiculous.

TL;DR - method bundles are not always bad. Try to use instantiable classes first. Fall back to "modules" only when needed.

Ray Toal
  • 1,305
  • 8
  • 11
0

Taking the given examples:

getMotorDataFromHTMLForm()
selectMotorFromUserRequirements($requirements)

These look like "factory" methods, that would return a Motor object. The second implies that either you're creating a new object to meet requirements, or you have a database or in-memory collection of motors that you're examining. In which case it should be a method on that. Or it could be a method on the requirements object.

getMotorManufacturers()

From where are you getting them? That's what this should be a method of.

canMotorCanHandleOperatingConditions($conditions)
computePowerConsumptionForMotor($id)

These look like they should be methods on Motor.

pjc50
  • 10,595
  • 1
  • 26
  • 29
  • Yes. it is a "bundle of possibly unrelated methods" (BOPUM for short). I agree with the Factory and Motor comments. `getMotorManufacturers` is to return all motor manufacturers from the database. I am not sure where that goes. It will take me some time to unravel this BOPUM to put things where they need to go.. – Dennis Jul 08 '15 at 14:13
  • I am getting `getMotorManufacturers` from the Database. Database cannot have a method ... Currently I have a DataMapper pattern that queries the database, initializes an array, and populates it with Motor Objects (also containing Manufacturer information), and then returns that array to the caller. The caller is my `MotorOperations` class, which in turn is called from a `ProductSelection` class (which contains an algorithm that is used to select Motors, and loaded motor information is the data for that algorithm) – Dennis Jul 08 '15 at 21:07
0

An object is a collection of methods and data that have high cohesion. They belong in a class because they are highly interrelated and state is retained.

This is true whether you use big up front design and attempt to model everything, or emergent design where you iterate and evolve the object into whatever fits the needs of the system at the time.

If you have no reason to retain state, you probably don't have any reason to instantiate an object which means there is probably no reason to have a class. Unless, the language your using doesn't have the ability to define a namespace other than using class. In which using class should be fine because it would be idiomatic.

I can't think of any negative aspects to using classes in this way other than the typical. Your inviting unnecessary cost and complexity by having to instantiate a "namespace". Anyone supporting this code will wonder where the data is costing additional cognitive load (most likely a one time cost per person). It's an unusual usage without any additional value.

dietbuddha
  • 8,677
  • 24
  • 36
0

Classes are used for several completely unrelated things. First they are used as data types (a class of data), to be able to collect potentially polymorphic sets of functions or procedures on specific types of data. Mutability/state here is not so relevant. Some languages have OO without state/mutability but still benefit group grouping, reuse/composition, and polymorphism (which is a property of message sending).

Secondly, they are used to represent/model objects from the real and imaginary/virtual worlds. Thise object representations, or just objects, might or might not be stateful/mutable, here, composition/reuse are still important, polymorphism (message sending) too. But the idea of a class being a data type fades here and classes become more like modules.

Thirdly, they can be used as a form of more programmable modules, potentially in addition to a language’s namespace system. Singleton objects (or singly constructable classes in languages where direct object representation is not possible) serve as modules. Singletons can leverage reuse/composition as well as polymorphism, they can also have state in some cases (stateful modules).

If you are applying any of these 3 main categories of OO-ness in your code, you are using OO. There is no need to use all aspects at all costs.

The criticism of OO languages usually boils down to being too state oriented: everything is polished in the OO department, but immutability and algebraic purity have to become mere afterthoughts. Languages such as Scala and F# are good showcases of multiparadigm (holistic?) techniques. Languages such as Haskell, where direct memory mutability, is not just impossible but absurd, yet where polymorphism, reuse/composition and data types excel above all.

Erik Kaplun
  • 471
  • 4
  • 12