2

Doesnt private members and methods inherently violate the open-closed principle? Given that private, protected and public modifiers are supported.

I came across this many times in codebases where developers use private modifiers for members and methods for whatever reason which in turn requires me to copy entire blocks of code to be able to extend it. I feel like many people just use private out of habit because its use cases are very nieche in my opinion and almost all the time protected does the job as well.

9
  • BTW. Apple removed “protected” from Swift. And Chris Lattner knows a thing or two about software development.
    – gnasher729
    May 15 at 12:35
  • 4
    If you insist on linking your problem to the OCP I would say private nembers enforce it rather than violate it: you are supposed to extend/inherit, not mess with the base class. May 15 at 12:50
  • 2
    private lets you do the closed bit
    – Ewan
    May 15 at 12:51
  • Sounds to me like the private modifier is doing exactly what it is supposed to do.
    – Ccm
    May 15 at 13:19
  • 1
    I think you've discovered out why that style of inheritance has fallen out of favor.
    – JimmyJames
    May 15 at 15:03

6 Answers 6

4

Thought experiment: imagine a component designed to be OCP-compliant, with certain extension points and public members, so it can be reused in a black-box fashion in several use cases. Imagine also the component has some or several private members.

Now, imagine the private members were all made public - then the same component would still be as reusable as before. So this makes it clear private members - at least technically - don't contribute to the OCP.

That still does not mean they violate the OCP. Nevertheless you are right - in real-world components, sometimes developers miss occasions for opening a possible extension point to the client by keeping something private, which should be made public. Usually, this involves more than just exchanging the keyword private by public, but sometimes this is all what appears to be needed.

However, one should not jump to the conclusion that it is better to make every member public in a reusable component "just in case". The OCP is usually only one of many goals you have to aim for when designing reusable components. Other typical goals are

  • to keep the component maintainable and evolvable,

  • to keep the number of breaking changes low when creating a new version

  • to keep the API of a component as simple as possible, so another dev has only to learn and understand the 5 public methods to use it and can ignore the 95 private methods which they don't care for.

And that's why private members are required - to keep the the impact of changes low, and the whole component comprehensible for a client. That's especially important when you don't know all the clients who are potentially reusing your component - by making a method or field private, you signal to them

  • you don't have to know what this method does when you just want to use this component

  • this part of the code might become subject to change at a later point in time

  • don't fiddle around with this member from the outside, you may accidentally break some invariant.

Hence, the design of reusable, long-living components is often a trade-off. If one

  • is 100% sure a component's source code will never-ever become subject to change, not even for a bug fix, and

  • does not care whether a component is used by clients in an anticipated "correct" way, or if clients may shoot themselves in the foot

then one may use only public members. But as soon as you want to provide updates and new releases, you have to find a balance between private and public members.

6

For inheritance to work well you need to design your base class with inheritance in mind. In that case you should carefully consider what properties and methods should be protected or private, as well as 'virtual' or 'abstract'.

But this is quite a bit of work, so most classes are just not designed for inheritance, and just make everything private. Ideally these should be marked as non-inheritable, but this is unfortunately often not done. Trying to inherit from a class that is not designed for it is likely a poor idea.

I would also recommend avoiding dogmatism, "open/closed principle" is a good idea, but it is possible to get carried away. Just like with all other design patterns you need to know what problem it addresses and where it is applicable.

If you are making an public API it is a very good idea to seriously think about what things users will want to extend, how, and many other design considerations. There is also a trend of Composition over inheritance, so you might want to consider other methods of extending behavior than inheritance.

If you are developing an internal class then you should have a good understanding of how the class is used. So modifications should have a lower cost.

1

When I make a method private, it means “it’s not designed to be reusable. If you want to reuse it, do it at your own risk and don’t come crying to me if it doesn’t work”.

Open/closed principle doesn’t come for free. Someone has to do serious work to implement it. The original developer said “I’m not paid to do it. And as far as I know, you ain’t gonna need it aka the YAGNI principle.

Now you needed the open/closed principle. And instead of implementing it, as you should have done, you did a copy/paste job, which is one of the worst mortal sins you could have committed. So you have nothing to complain about. Implementing the open/closed principle was your job and you refused to do it.

4
  • No it was not my job because im working with frameworks and libraries. My point is that if you use private methods you prohibit the usage in any child class and therefor limit the ability to extend it because you might wanna call it. Therefore theres no other solution than to copy it because you need that exact behavior in the child class. For example when extending a public method which calls a private method. May 15 at 13:45
  • @CodeSpirit the only reason you even know about the existence of the private method is cause you decompiled or had access to the code. If that wasn't the case, you wouldn't have the problem now. The private method may change or be deleted in the future, you shouldn't relay on its existence.
    – Ccm
    May 15 at 15:39
  • Code spirit. I bet your job is primarily to create code that works and not leave a maintenance nightmare behind. And that’s exactly what you did.
    – gnasher729
    May 15 at 15:50
  • And as I said, “private” doesn’t limit your ability to use it, it’s a warning sign. Here be dragons. Enter at your own risk. Like a fence around a building that will be demolished with dynamite in an hour. To you, the fence limits your ability to enter the building.
    – gnasher729
    May 15 at 15:54
1

Private methods does not in themselves violate the open-closed principle, but a class with only private methods would violate the principle because such a class is not extensible.

Your problem with having to copy-paste code points to a more fundamental problem with the open-closed principle, and the reason the principle have largely been abandoned for real-world development. (The principle mostly only exist in academia and teaching at this point).

The fundamental problem is: It is not possible to design a class to be extensible for any purpose. Extensibility have to be deliberately designed. The open-closed principle can only really be followed if the the general purpose of the extension was already predicted when the class was designed.

12
  • "the reason the principle have largely been abandoned for real-world development. (The principle mostly only exist in academia and teaching at this point)" - what a huge misconception. The pricinple is used in real-world development wherever reusable libraries and frameworks exist.
    – Doc Brown
    May 17 at 6:03
  • @DocBrown Many libraries and frameworks use semantic versioning (which is a controlled way to introduce changes in published libraries) because they realize keeping modules closed is neither practical nor desirable. (To be clear, I'm referring to the original definition of the open-closed principle by Bertrand Meyer.)
    – JacquesB
    May 17 at 15:15
  • "It is not possible to design a class to be extensible for any purpose. Extensibility have to be deliberately designed" - 100% ack. The open-closed principle can only really be followed if the the general purpose of the extension was already predicted when the class was designed. - I think this is not accurate Replace "OCP" by "keeping the module closed" in that former sentence, and I will agree. And I don't think Meyer wrote something different, I scanned the related pages.
    – Doc Brown
    May 17 at 15:42
  • @DocBrown I'm not sure what distinction you are making there? The open-closed principle wouldn't be the open-closed principle if you remove the "closed" part.
    – JacquesB
    May 18 at 12:53
  • Jacques, I disagree that one follows (or does nott follow) the OCP after a class was designed (and AFAIK neither Meyers nor Martin wrote something like that). Not the client who uses a class or component is the protagonist of the OCP, but the designer of the class, before the class is "closed" and handed over to a client. The client may or may not be able to reuse a component in a black-box fashion when the designer missed to provide the necessary extension points, but that is not "breaking the OCP" - the role "client" is technically not able to break the OCP,
    – Doc Brown
    May 18 at 16:21
1

Open close principle states to be open for extension while closed for modification. Are private fields and methods visible while extending? No? Then the answer to...

Do private members/methods inherently violate the open-closed principle?

is no.

When extending a model developed by another author that isn't reachable any further figure scenarios that support the purpose of used access modifiers and when those scenarios are different than what is intended for the future implementations redesign the implementation following whatever principles are intended to follow without considering them. Most of the times while redesigning the redesigned implementation gets lost almost entirely.

developers use private modifiers for members and methods for whatever reason

Is common to use private access modifier for methods that are implemented to reduce the size of a lengthy complex method under the recommendation that methods should have at most three to five lines of code. I don't have an answer for the question "where afore mentioned recommendation sources from?" although I've noticed it mentioned often.

0

The argument for private fields is that by changing their values in a derived class you modify the functionality of the original class.

eg.

class Reactor
{
   public int temp;
   public void AdjustCoolingRods()
   {
     if(temp > 100) { raiseRods() }
     else { lowerRods() }
   }
}

class MyReactor : Reactor
{
   public void PlayWelcomeMessageOnBoot()
   {
      temp = 0;
   }
}

Clearly by making temp private we protect the AdjustCoolingRods function against modified behaviour

So its the "Closed" part of the Open Closed principle which the private access modifier is complying with.

I'm basing this largely off OCP: The Open-Closed Principle : Robert Martin

Make all Member Variables Private. This is one of the most commonly held of all the conventions of OOD. Member variables of classes should be known only to the methods of the class that defines them. Member variables should never be known to any other class, including derived classes. Thus they should be declared private, rather than public or protected. In light of the open-closed principle, the reason for this convention ought to be clear. When the member variables of a class change, every function that depends upon those variables must be changed. Thus, no function that depends upon a variable can be closed with respect to that variable.

8
  • I think there is a fundamental misunderstanding here. "Closed for modification" means "you don't have to change the source code", not "Closed against modifying a behaviour through some public member".
    – Doc Brown
    May 17 at 6:09
  • hmm i think you are wrong on that. let me find the source
    – Ewan
    May 17 at 9:05
  • there added quote and link
    – Ewan
    May 17 at 9:27
  • Yes, that linked PDF explains it well, see page 2: "They are “Closed for Modification”. The source code of such a module is inviolate. No one is allowed to make source code changes to it.. Bob Martin speaks about changing the source code of members, not the values which are assigned to them.
    – Doc Brown
    May 17 at 10:40
  • I mean, that's the one liner description at the top, but the rest of the paper goes into the details, I've adapted the example to make it more clear, but its there starting page 9 Heuristics and Conventions. "OCP is the root motivation behind... Make all member vars private"
    – Ewan
    May 17 at 12:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.