Live data from Hacker News

Ask HN: Why do you make class members private?

news.ycombinator.com

91–100 of 117 posts

Re: Ask HN: Why do you make class members private?

#91
History time: In 1972, David Parnas wrote a paper about "Information Hiding," and a few years later Fred Brooks wrote The Mythical Man-Month, possibly the most influential book about software engineering, which largely discounted the value of information hiding. 20 years later, in an updated anniversary edition of The Mythical Man-Month, Brooks wrote "Parnas was right, and I was wrong about information hiding."

Coming from Fred Brooks, this was an enormous admission! What is this amazing "information hiding?" It is separating interface from implementation, leaving one public and the other private. It is accomplished, among other means, by marking things "private."

This is the one thing in 20 years that Brooks found to be valuable in increasing programmer productivity in terms of essential complexity. Marking implementation details as private reduces the essential complexity of the code.

By the way, in some of your comments you talk about "everyone" having access to things, as if that makes a difference. Marking things as "private" is not about closing off access to particular people. It's not a security measure. It's about reducing the complexity of a given class by ensuring that the number of access points to that class are limited. That could affect other teams, sure, but it could also affect future-you, or you-working-on-other-class.

Re: Ask HN: Why do you make class members private?

#92
post #60

Encapsulation is a founding principle of OOP. You should not be able to directly tool with a class' internals, but use its methods to interact with it. The practical reason is that this way you have limited paths (methods) with which the inner workings of a class can be modified with, whereas if anything would be public, any other obejct would be able to change a class' status rendering debugging incredibly more comp…

> Encapsulation is a founding principle of OOP.

The more fundamental principle that predates OOP is: Abstraction

https://en.wikipedia.org/wiki/Abstraction_(computer_science)

Re: Ask HN: Why do you make class members private?

#93
post #51

Earlier quoted context omitted.

Can we acknowledge yet that the concept of classes as tiny programs with tiny APIs has failed? [...] mainly based around working mostly in C++ Speaking as a C# developer, I think the concept of classes as tiny programs with tiny APIs works very well.

It's been a decade since I used C# but the corporate design pattern culture of that language back then turned me off of it forever. Everything looked like this: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris... Maybe it's better now but the Java/C# practice of shoveling largely empty classes around with an IDE isn't something I'd point to as a good example.

It's been a decade since I used C#

Well the last time I regularly used C++ was Borland C++ 3.1 from 1992. I'm not sure you'd be interested in my opinions on the language from 30 years ago.

Re: Ask HN: Why do you make class members private?

#94
post #66

> To clarify, I'm only talking about code in the same project that everyone has access to. I'm not talking about defining an API for other people to use that don't have access to the code, like when you make a library. A lot of people are ignoring this part of the question. The primary usefulness of object-oriented programming is scope control . Dependencies kill teams, and scope control helps them survive. The more…

> Dependencies kill teams Do you mean that when you have structured the organization so that each class is worked on by at most one team, you want to reduce the number of dependencies between classes in order to reduce the number of dependencies between teams? > they have to consider all possible points of entry So is this basically what I mentioned, that you want to reduce the number of places you have to look in wh…

To the first question:

By "dependencies kill teams" I mean all the forms of dependencies: Database dependencies, web service dependencies, library dependencies, across teams, across organizations, and so on.

Arguably internal dependencies inside a program are the least lethal. You are largely doing others the favor of implicit documentation by using scope control, a guaranteed statement of "This is never used outside this file". They might be able to figure as much out by grepping, remove & recompile, or IDE-based tools. "Greppability" is often part of the solution when dealing with database & http dependencies.

As for the second question, basically, yes.

Re: Ask HN: Why do you make class members private?

#95

>I'm only talking about code in the same project that everyone has access to. I'm not talking about defining an API for other people to use Even within a single module of code, your public interfaces are "APIs". If I write a class that displays a paged interface in a popup modal, there is no relevant difference between a member of my team utilizing that class (from within the same module) and other people using it (a…

> there is no relevant difference between a member of my team utilizing that class (from within the same module) and other people using it (as a library I have published).

The difference between a team member and a library user is that the team member works in the same project while library users have their own projects. So if you change something inside the class, you can change all the uses of that class in your project but you can't change other people's projects. That's why I added the clarification, because there is a very obvious reason to be strict about the API of a library that other people use: you can't change those uses.

Re: Ask HN: Why do you make class members private?

#96
The following is a public API for a Car:

- Steering wheel

- Transmission

- Brakes and Gas pedal

- Doors and Windows, etc.

The following is a private API for a Car:

- The inner workings of the engine

- The inner workings of the battery

- Smart break system, internal wiring, etc.

All users of the Car only care about how to drive it with as little knowledge as possible.

Now Mazda can do a full recall and upgrade the smart breaking systems internally but millions of drivers around the world don't have to "learn" anything new, they can happily continue using the public API.

It makes refactoring much easier, reduces dependency and enables duct typing (in supported languages) via message passing for objects with a common public API. You also don't have to perform shotgun surgery[0] when changing classes..

[0] https://refactoring.guru/smells/shotgun-surgery

Re: Ask HN: Why do you make class members private?

#97
post #90

Earlier quoted context omitted.

1. It's private, only internal routines can use it. You aren't telling anyone to avoid using it, you are constraining where it can be used. You can use it directly in every internal routine if you want, that's not a problem. But no one outside the class/module can directly access it so if you change it (in whatever fashion) then those outside users will not be impacted because they are only dependent on the public in…

1. So it's not to make it easier to change things? Otherwise what's the difference, in difficulty to change things, between using a member in 20 places outside of the class and 20 places inside the class? It's the same amount of code to change if you change the member. > But no one outside the class/module can directly access it Everyone can access all the code. > those outside users will not be impacted What do you…

>> But no one outside the class/module can directly access it

> Everyone can access all the code.

I don't care what everyone can access (in terms of altering on a filesystem and code repository). It's about what the code can access.

  public class BoundedStack {
    ...
    private int limit; // initialized in constructor
    private T[] array;
    private int top = 0;
  }
Yes. Everyone who can see this code can alter this code, who cares? What matters is that users of this class cannot, in a separate module/class, directly access those three fields. You cannot, after marking these as private, do this inside some other class or module:

  void some_method() {
    BoundedStack stack = new BoundedStack(100);
    ...
    stack.top = 200; // invalid
    ...
  }
That's invalid code, and that's a good thing. top is only modifiable by the BoundedStack class's own methods, which ensures that the state is always valid (so long as the code itself is correct, this is a trivial example to test so that's easy to verify one way or the other).

Using private, here, is moving a convention (like _ in Python or just a verbal agreement or a note in the documentation) to a compiler checked thing. It makes it guaranteed that users cannot (modulo reflection facilities in some languages, but that's jumping through hoops, but that's their problem when it breaks, not mine) access these without going through your intended interfaces.

>> those outside users will not be impacted

> What do you mean that they will not be impacted? If I change the internal array and all the places where it's used, nobody might even notice it. Or is the assumption that one team can only change inside the class and other teams can only change outside of the class? Remember that we assume that everyone has access to the all the code.

What I mean is that in the above, you can change the manner in which BoundedStack (or whatever the module is) is implemented and the interface remains the same. Users still have access to peek, pop, push, and whatever other methods you provided. What they cannot do is assume (you know what assuming does, right?) that the underlying representation is stable and bypass your intended interfaces. BoundedStack could switch to using a LinkedList for all the user needs to care, but if they assume it's an array backing it and have access to that array they might write something like this (even assuming they do everything as safely as possible so that this is a valid piece of data they're accessing, but in an unintended way):

  void bad_user() {
    BoundedStack stack = new BoundedStack(100);
    ...
    int a_datum = stack.array[n]; // where `n`, to be generous, is a valid item at this point
    ...
  }
Now let's suppose you used public fields and that currently works. Later on you decide to switch to a linked list. Hypothetical rationale: Users often create large bounds for the stack for exceptional circumstances, but have small stacks 99% of the time; a linked list ends up using a lot less memory because it doesn't allocate a massive, and mostly unused, array; access is sufficiently infrequent that the allocations are a non-issue. For some reason you left the name array in place, so the user's code still works as is, or even if you did change it they changed the name (or maybe you did when you applied the name change to the whole codebase, oops). Except that array[n] is now a linear operation and not constant time. Suddenly there's a massive performance regression because the users:

1. Did something unexpected with the code (why the fuck are they using a stack if they want to access anything but the top?).

2. Assumed the internal implementation details were stable.

It doesn't matter how many teams are involved, you can (and ought) to use private even for yourself or for one team. It makes the system far more maintainable and reliable to either have an actual language notion of private or a community consensus on what is private (like _ prefixed member variables in Python). It reduces coupling, which is one of the number one ways to cripple development as a system grows in size.

Re: Ask HN: Why do you make class members private?

#99

Earlier quoted context omitted.

It's been a decade since I used C# but the corporate design pattern culture of that language back then turned me off of it forever. Everything looked like this: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris... Maybe it's better now but the Java/C# practice of shoveling largely empty classes around with an IDE isn't something I'd point to as a good example.

Wow, what a repo. I can't even tell if the author is serious or this is some tinderbox-dry satire, bravo either way. I'm sad that I've worked with plenty of codebases that look exactly like that and I twitched a little bit browsing around. :)

From the readme: > Although this project is intended as satire, we take openness and inclusivity very seriously. To that end we have adopted the following code of conduct.

Re: Ask HN: Why do you make class members private?

#100
post #73

Earlier quoted context omitted.

The language is not relevant to the question. Making variables and methods private means making them inaccessible outside the class and I gave the typical reasons/best practices for that.

> Making variables and methods private means making them inaccessible outside the class and I gave the typical reasons/best practices for that. The point they are making is in python there's no private method, everything is public. There's only a convention of "avoid using anything starting with "_"

Yes but that point is irrelevant to the question...
Post reply on HN