0

I have a group of classes (let's say B,C,D,E) that basically represent specific operations a user can execute. I would like to have a single point of access for creating these object and launch their executions.

My first idea to accomplish that is to create another class (let's say class A) which will hide the complexity of creating the operation object and will call the related execution methods.

The classes B,C,D,E will implements a common interface in order to simplify the call of the specific operation.

My concern is how to prevent the possibility, by other classes, to create and directly use instances of classes B,C,D,E. I thought to define them as nested classes for class A: but this would affect the possibility to easily add more operations without touching the source file of class A.

In my implementation A is a Singleton.

How can I restrict the visibility of a group of classes only to a single class?

Edit: The application has to be written in C++

13
  • 2
    Which programming language do you use? Java would support this using modules introduced in Java 9.
    – user330854
    Aug 30, 2019 at 9:12
  • 1
    Since Java did not support this kind of control over readability until the Java Module System was introduced in Java 9, it is hard to imagine a language independent pattern. I am not a C++ programmer and have no knowledge about how visibility is controlled by it.
    – user330854
    Aug 30, 2019 at 9:35
  • 2
    @AndreaGiordano ok, so it‘s a typical facade pattern ( medium.com/@andreaspoyias/… ) and the question is a “how can I ... in c++”. I’d then suggest to look on stackoverflow (e.g. stackoverflow.com/questions/20401372/… ) . The easiest way is certainly not to include B..E headers, except in the cpp of A. If you are affraid of an accidental include, make the constructors of these classes protected and A a friend.
    – Christophe
    Aug 30, 2019 at 12:38
  • 2
    @JörgWMittag: if I see a question where an answer would be pretty language dependent (with no programming language mentioned), I would hesitate to answer the question - chances are high that either the OP adds a language afterwards, or if not, the question gets closed as "too broad" ;-)
    – Doc Brown
    Aug 30, 2019 at 12:56
  • 1
    ... and I think people should not be critized for trying to prevent their question getting closed.
    – Doc Brown
    Aug 30, 2019 at 13:07

2 Answers 2

1

I thought to define them as nested classes for class A: but this would affect the possibility to easily add more operations without touching the source file of class A.

If your problem is solely with not wanting to change the file (for what I presume are subversioning concerns), and you don't mind changing the class itself, then partial classes solve the issue for you.

This allows you to spread your parent class over multiple files, which in this case you can do to separate your parent class file from your nested class file(s).

/////////////////////////////// File: A.cs

partial ref class A
{
    // Things for A
};

/////////////////////////////// File: B.cs

partial ref class A
{
    class B
    {
        // Things for B
    }
};

/////////////////////////////// And so on...

Whether you group B,C,D,E in a single file or not is up to you. It depends on the size of the classes and how cohesive they are.

0

This can be solved in Ruby, for example, by making B, C, D, and E private constants of A:

class A
  class CommonInterface
    # whatever your common interface is
  end

  class B
    # do stuff
  end

  class C
    # do stuff
  end

  class D
    # do stuff
  end

  class E
    # do stuff
  end

  private_constant :CommonInterface, :B, :C, :D, :E
end

Or, by making B, C, D, and E instance variables of A:

class A
  common_interface = Class.new do
    # whatever your common interface is
  end

  @b = Class.new(common_interface) do
    # do stuff
  end

  @c = Class.new(common_interface) do
    # do stuff
  end

  @d = Class.new(common_interface) do
    # do stuff
  end

  @e = Class.new(common_interface) do
    # do stuff
  end
end

This is as good as it gets in the absence of reflection. (It is still possible to break encapsulation using reflective methods such as Object#instance_variable_get or Module#const_get.)

If you want to protect yourself against reflection, too, then you can use local variables and closures.

class A
  common_interface = Class.new do
    # whatever your common interface is
  end

  b = Class.new(common_interface) do
    # do stuff
  end

  c = Class.new(common_interface) do
    # do stuff
  end

  d = Class.new(common_interface) do
    # do stuff
  end

  e = Class.new(common_interface) do
    # do stuff
  end
end

In Newspeak and Scala, you could simply make the classes private.

2
  • Yes, something like this could be done in Java using private classes, too.
    – user330854
    Aug 30, 2019 at 9:50
  • 1
    Did you notice the OP added "C++" to their question afterwards?
    – Doc Brown
    Aug 30, 2019 at 11:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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