1

In the code below, does passing a private member, _field, from class Foo as an external method parameter (Bar.DoSomething(_field)) violate the Open/Closed principle in SOLID programming practices?

In object-oriented programming, the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behaviour to be extended without modifying its source code.

As I understand it, entities should be open for extension, but closed to modification. However, in this case, _field is set once in the constructor of Foo and is readonly. Is passing a private member to an external method's prameter violate Open/Closed principle or some other best practice?

  public class Foo
  {
    private readonly int _field;

    public Foo(int input)
    {
      _field = input;
    }

    private void FooDoSomething()
    {
      Bar.BarDoSomething(_field); //Breaking Open/Closed Principle?
    }
  }

  public static class Bar
  {
    public static void BarDoSomething(int input)
    {
      //Something happens
    }
  }
David Vogel
  • 465
  • 8
  • 23

1 Answers1

3

No, this does not violate the open/closed principle. From the standpoint of Bar, input isn't an internal field belonging to Foo. It's just an integer. The internal state of Foo remains hidden inside the class.

Going a step further, unless you were to specify ref when passing the parameter,

Bar.BarDoSomething(ref _field);

Bar can't even modify the value of _field. The interaction is one-way. Foo is telling Bar to do something. That's good.

To clarify - even if ref was used and Bar could modify the value that wouldn't have any bearing on the open/closed principle. But if the purpose of Bar.DoSomething was to return a value then it would be better as a function that returns an int rather than a method that modifies one. That way the caller could get the value and decide whether it wanted to update _field.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • I interpreted the article completely differently - from what I understood, any non-sealed class would be open (for extension), as it can be extended without modifying its source code (via inheritance). I'm not sure, however, how to interpret 'closed'... – Aconcagua Apr 27 '16 at 20:20
  • In the context of the question asked - there is no behaviour modification involved in any way, so I'd say even if a non-final variable would have been modified by reference, the principle is not violated. Did I understand something wrong? – Aconcagua Apr 27 '16 at 20:23
  • I can't really draw a relation from the example to the open/closed principle because the example isn't really even in the ballpark of violating or not violating that principle. So I was just answering, "No, it doesn't violate it." I could understand somewhat why the question arose. But even if the value was modified it wouldn't have any bearing on that principle. – Scott Hannen Apr 27 '16 at 20:52
  • In practice I understand the "closed" part as meaning that the internals of a class are hidden even from derived classes. So if you inherit from `Foo` then the *base* class can modify `_field` but derived classes can't. So while you can extend its behavior, you can still cast an inherited class as `Foo` and trust it to behave exactly the same way. The exception would be methods that are intended to be overridden, but you'd still want to determine what those overridden methods can or can't change in the object's internal state. – Scott Hannen Apr 27 '16 at 21:08
  • Can we the agree then, that - if we are strict - a class is closed if it does not contain any virtual methods? (This would eliminate the exception.) – Aconcagua Apr 27 '16 at 21:16
  • A class could still be closed with virtual methods. It would just need to be designed to control what access those methods would have to its own state. In a sense the base class would almost treat those methods as belonging to another class, deciding what to expose to them. – Scott Hannen Apr 27 '16 at 21:21