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++

Akinn
  • 109
  • 3

2 Answers2

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.

Flater
  • 58,824
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.

Jörg W Mittag
  • 104,619