Live data from Hacker News

Classes vs. Data Structures

blog.cleancoder.com

151–160 of 184 posts

Re: Classes vs. Data Structures

#151

People are starting to use data oriented design instead of OOP. Data oriented design doesn't hide state, is generally faster and easier to comprehend as it doesn't abstract too much. https://www.youtube.com/watch?v=QM1iUe6IofM https://www.youtube.com/watch?v=yy8jQgmhbAU https://www.youtube.com/watch?v=rX0ItVEVjHc

Data oriented design makes sense in video games where perfomance Is very important, but in most business applications having good abstractions which are flexible and easily maintainable is much more important than optimising for cache usage.

Re: Classes vs. Data Structures

#152
post #107

Earlier quoted context omitted.

I think part of the problem is that many popular languages now default to using two very different behaviours for elementary tasks like passing variables or parameters around, depending on whether the variable is a "reference type" or a "value type". Simple things like numbers have value semantics. Objects and whatever else works a bit like an object in your language have reference semantics. If you want a reference…

Assembly was fun, but I understand it would be cruel and not so useful to teach it to today students, but I can't figure out how someone can learn some concepts whithout the "memory is an array" model. My favourite book at college about (the real) data structures started building the array, even if it was already implemented in the language.

It is not necessary to go right down to assembly level to introduce these concepts, though. Just a language with a transparent memory storage model and explicit reference vs value distinction is enough. C is still the lingua franca of the programming world and IMHO it is useful to know basic C for these reasons even if you rarely write much code in it.

Re: Classes vs. Data Structures

#153
Interesting read. What immediately sprung to my mind was Rust's Trait system which sort of manages to give you the best of both worlds. With Traits you can implement common behaviour/functions for multiple datastructures.

When I started using Rust I wasn’t used at all to seperate data and behaviour that strictly, but it makes sense. OOP paradigms were still hardwired in my head so the hardest part was actually wanting to do it in that decoupled way. Something about a car object that has wheel objects and a car.drive() function gives you a good feeling as a programmer, but sometimes it is more effective to stay with the data structure and describe the car as a struct of vectors which implement a Driveable trait..

Re: Classes vs. Data Structures

#155
post #149

Earlier quoted context omitted.

You don't lose anything by strictly enforcing the encapsulation because you can always explicitly provide low level methods into the data structures. But then you're not really gaining anything either, unless perhaps you have some mechanism to enforce that the low-level access should only be used in specific circumstances when it is deliberately intended. It's like writing classes that have a few data members, but th…

I think to some degree its a matter of opinion but I couldn't disagree more. The argument for abstraction at the procedure level seems obvious if you've ever used an interface or private members. I think you have some picture in your head where everything has to be abstracted in a needlessly obtuse way to be an object. If you have some DTO, the fields are the contract so its fine if they're public. (In Java in partic…

I am simply suggesting that religiously hiding implementation of simple data structures behind formal interfaces may be excessive.

You seem to be assuming a certain style of programming or type of programming language here, along the lines of mainstream OOP languages. There are other options, from low level languages like C to languages where algebraic data types and pattern matching are bread and butter, that do not attempt to conceal true representations of simple data structures in that way. The sky does not fall! :-)

Sometimes it is useful to be able to drop down to that level if the provided set of standard functions to work with that data structure does not meet your needs. You might want to support some new access pattern that is not offered in a convenient form by the tools available in the provided interface, for example.

Sometimes you might want to know, say, which order the axes go in for some multi-dimensional data structure, because writing your algorithms to match can have a profound effect on real world performance. And in this sort of situation, the advantages of being explicit about that can far outweigh the theoretical benefits of being able to replace the internal representation transparently, which is something you are extremely unlikely to be doing in an established system where this kind of issue arises anyway.

Re: Classes vs. Data Structures

#156

Earlier quoted context omitted.

You can change the internal representation while doing transformations in the getter to preserve compatibility. With collections, you can export contents through an Iterable, or to Array, or any number of other strategies, without coupling the consumer to your internal representation.

Of course, but what I am questioning here is how often we really do change internal representations of simple data structures. The theoretical benefit of hiding every representation behind an interface is clear, but any abstraction also has a potential cost if it creates a barrier to doing something useful and/or becomes leaky. You can still provide standardised interfaces for things like iteration along with a data…

My perspective is from a heavy Java background.

By using the standardised interfaces for everything you can change the implementation without changing how you work on it.

For example, my service that stores a collection in a database. I could write my service so that it takes in a Collection, rather than an ArrayList, because then anyone using it can pass in a Set (no duplicates), CopyOnWriteArrayList, TreeSet (ordered set).

By hiding internals and using the interface, I can pick the abstraction I need and give more freedom to those using my classes.

Another example. Once Project Valhalla and Value types come in, LinkedList might be changed to use value types for Nodes. Lets say I've tightly coupled my code to the implementation of LinkedList. This could potentially break my code.

Re: Classes vs. Data Structures

#157

People are starting to use data oriented design instead of OOP. Data oriented design doesn't hide state, is generally faster and easier to comprehend as it doesn't abstract too much. https://www.youtube.com/watch?v=QM1iUe6IofM https://www.youtube.com/watch?v=yy8jQgmhbAU https://www.youtube.com/watch?v=rX0ItVEVjHc

Data oriented design makes sense in video games where perfomance Is very important, but in most business applications having good abstractions which are flexible and easily maintainable is much more important than optimising for cache usage.

I tend to disagree — although I thought the same one or two years ago. Data oriented design doesn’t automatically mean you have to sacrifice useful abstractions on the altar of performance. You’ll have to find different abstractions and ways of composing them together to get a maintainable, flexible result.

In fact I find good data driven designs easier to maintain than good OOP ones..

Re: Classes vs. Data Structures

#158

Earlier quoted context omitted.

Of course, but what I am questioning here is how often we really do change internal representations of simple data structures. The theoretical benefit of hiding every representation behind an interface is clear, but any abstraction also has a potential cost if it creates a barrier to doing something useful and/or becomes leaky. You can still provide standardised interfaces for things like iteration along with a data…

My perspective is from a heavy Java background. By using the standardised interfaces for everything you can change the implementation without changing how you work on it. For example, my service that stores a collection in a database. I could write my service so that it takes in a Collection, rather than an ArrayList, because then anyone using it can pass in a Set (no duplicates), CopyOnWriteArrayList, TreeSet (order…

And there is nothing wrong with writing generic code like that! Just because you can access the specific representation of the underlying data, that does not mean you have to or would do so routinely. In languages that do tend to expose simple data structures directly, it is still normal to provide standardised tools for accessing and manipulating them, and most of the time that is probably still how you would interact with them.

Regarding your second example, if you are working with an explicit representation then you simply would not make a breaking change like that. Instead you would create a new data structure with the new representation, which other code can then choose to use instead if it wants to. Again, nothing about this prevents both versions from also providing equivalent functions to access them in the same way where that makes sense or writing other code in terms of those functions rather than tied directly to the specific implementation.

Re: Classes vs. Data Structures

#159
I like the shapes problem because I actually encountered it and it made me think.

I'm not sure about the switch approach described in the post:

  function area(shape)
    switch shape.type
      case "square": return shape.side ** 2
      case "circle": return 2 * PI * shape.radius
      case "triangle": return ... 
      case "segment": return 0
      case "polygon": return ...
      ...
      case "oval": return ...
You can have a lot of cases, some of them requiring non trivial code... Eventually you write a function for each case and it's more work than adding a method for each shape because you still need to write the switch...

Classes seem work better than structures here.

But then you want to handle intersections

The switch approach doesn't seem realistic:

  function intersection(shapeA, shapeB)
    if(shapeA.type == "circle" AND shapeB.type == "circle")...
    if(shapeA.type == "circle" AND shapeB.type == "square")...
    if(shapeA.type == "square" AND shapeB.type == "circle")...
    ...//uh oh you have nShapes**2 cases to handle
But java classes or not better: where do you define Circle-Square intersection? In Circle? In Square?

Even with multiple dispatch the solution is not ideal. You now have some things related to Circle (area, perimeter...) in the Circle.blub file, and intersection(Circle, Circle) wich only works with Circles is now in intersections.blub...

I don't see a good solution and sometimes I feel like the problem is more with our tools (code in text files) rather than programming paradigms

Re: Classes vs. Data Structures

#160
post #33
post #19

Earlier quoted context omitted.

I get that in your application, you may want to keep a linked list behind its interface 90% of the time. However, considering your system as a whole, at some point you may want to take that linked list data and write it to a database, in which case the cleanest thing is to bypass the interface and extract the "data structure object" so to speak and deal with it in a database-related object, rather than encumbering yo…

This is a violation of OOP. Instead, consider methods that produce and consume a serialized representation of the data instead. Things like Java serialization and Python pickle attempt to do what you say and are considered failures (or at least security risks) because they allow a third party to act on object implementation internals. Security aside, a denormalized representation of data could be different than the i…

> This is a violation of OOP.

and this is because of that that OOP has a bad name.

It's ok to violate "great principles" when writing software. What I have never seen pan out is dogmatic application of principles.

Post reply on HN