loading...

Please don't write a class

twitter logo github logo ・1 min read

Please don't start by writing a class for every thinkable entity. Please don't start writing a Mammal class for a Dog object to inherit, thank you.

OOP is not a silver bullet to every programming problem. It just makes code less enjoyable to read and obscures pure algorithmic beauty.

twitter logo DISCUSS (15)
markdown guide
 
public class Answer {
  public String toString() {
    return "Agreed.";
  }
}
 
 

An example in interface in Go and trait in Rust (not ideal for this argument, but at least simpler, less overhead than classes)


type Dog interface {
        Bark(n int)
        Feed(food string)
        RollOver(n int)
}


trait Dog {
    fn bark(&self, n: i32);
    fn feed(&self, food: &'static str);
    fn roll_over(&self, n: i32);
}


Really interesting that these two new languages have no classes.

 

You're missing the point: that example is completely useless without some idea of what the business requirements are.

If I were designing something like Microsoft Bob, then I wouldn't have a Dog class at all. There might be a class for the visual character in general, but behind that the different avatars (the dog, the dude, I don't remember what the other ones were) can just be data files with no code at all. If I were designing a video game, the dog might be built up of a rendering model plus a number of Components that handle different behaviors that get linked up with the dog (some of them might only ever be used with the dog, but some wouldn't). And if I were tracking pets in a database, the only distinction between a dog or some other animal would be a single column; again, no dedicated dog-specific code here.

 

Thanks for the comment.

I invite you not to get bogged down by my examples. I was just suggesting an alternative.

My point being when something is simple enough to maybe solve with functions, maybe there's no need to jump to writing classes from the get-go.

No one is suggesting classes are bad here.

 

Well said, sir! I think there's too much extremism in development these days (Java sucks, FP rules, JS is horrible, etc., etc.)

No one is saying Java sucks, or we shouldn't write classes. Classes are great when dealing with complex projects, but themselves introduce overheads. Just have to be wary of writing classes for everything.

(Java does make programmers write class for everything though. Just saying)

 

I mean, while I completely agree that OOP is not a silver bullet, I would be curious as to the algorithm you suggest for Dog... 😜

 

Interface is one way to solve this entity problem. It provides an equally nice abstraction without carrying over lots of baggages. Also composition / mixin is a nice way. In non-OOP languages like Haskell or Erlang, problems can be solved mostly with functions and modules.

What I meant was if the problem's simple, there might not be a need in the first place for Dog to inheriting anything or to even be a Dog (with a capitalized D).

IMO It's better to be wary of writing classes than to jump to it as a first thought. You'd be surprised how meta it can feel to not having to strictly establish something as a definite being :)

 

Dog is not a new defintion, but an attribute of mammal in this case.

 

I disagree with this wholeheartedly. Classes are generally a GREAT way to separate logic into discrete pieces. When I go back to old code, I usually am very happy when the single thing I want to change is isolated in a class. For example: Logger, FileNameCreater, TradeQuoteMerger, etc. Creating a class even for very small operations makes testing, refactoring, and reading easier (given you name it well).

I think your statement would better as "Do not make an abstract/super class for every class". Dog does not need Mammal, but Dog is a GREAT class to create.

 

Instead of writing a class, an alternative would be writing a type (but on paper). A subtle distinction but consider this. For some problems it is helpful to think about your data and view the problem as a series of data transformations: data-oriented programming. In such cases you don't have a single dog that you want to invoke a member function on, and then call another one, but a thousand dogs that you want to perform the same function on all at once.

Also instead of having a large granular Dog type you could split it into different aspects, possibly using composition or AoS/SoA style held in completely separate collections, that together act as if they were a dog. This has the potential to scale better, not in just better design but performance as well. So think about the types, and think about functions using those types, but the former and latter don't necessarily need to be joined together (via a class).

 
 
Classic DEV Post from Dec 17 '19

Landing the First Job

Part 4 of DEV Student Series

Joe Chasinga profile image
Co-founder of Referkit - developer-first referral program and invitation campaign API and SDK for app launches. Go programmer. Hobby Prologuer.
Join dev.to

Guaranteed to make you a better developer or your money back