So I'm writing a Flocking System (http://www.red3d.com/cwr/boids/).

Each boid calculates it's vectors, I would like to draw these vectors with a helper class for debugging purposes.

Who should implement the DrawAllLines function ?

Please note that I'm using c#, so there is no friend functionality like in C++.

Please also note, that DrawAllLines is much bigger in the reality, that's why I would like to move that code to an other class.

Attempt #1:

Boid

public class Boid
{
    private Vector3 cohesion;
    private Vector3 separation;
    private Vector3 aligment;

    public void DrawLines()
    {
        DrawLine(cohesion);
        DrawLine(separation);
        DrawLine(alignment);
    }
}

Debug

public class Debug{
    public DrawAllLines()
    {
        foreach(Boid b in allboids)
        {
            b.DrawLines()
        }
    }
}

Attempt #2

Boid

public class Boid
{
    public Vector3 cohesion;
    public Vector3 separation;
    public Vector3 aligment;
}

Debug

public class Debug()
{
    public void DrawAllLines()
    {
            foreach(Boid b in allboids)
            {
                DrawLine(b.cohesion);
                DrawLine(b.separation);
                DrawLine(b.alignment);
            }
    }
}
up vote 1 down vote accepted

There are several related things we want to tease apart,

  1. Information hiding.
  2. Access restriction.
  3. Responsibilities.

In our first case we have the Boid hiding its information via access restriction (by making those fields private), which results in the problem that any responsibility requiring that information must be assumed by the class itself. This leads to code that tightly couples functionality and becomes hard to test, maintain and extend.

Our second attempt gives up on access restriction and information hiding in order to allow another class to take up the responsibility of drawing the Boid.

In this case I would say the second attempt is better than the first, but that what would make it even better would be to make Boid immutable or at least have those properties read-only.

There's no simple formula for what to do about these three aspects of our design, but we can come up with some simple maxims

  1. Do not hide information about your core domain.
  2. Do hide information if it being public would allow your design to be compromised.
  3. Keep access restriction simple. If you find yourself wishing to use a friend/internal/package-level access modifier there's likely something wrong with the design.
  4. Information hiding allows an object to maintain clear ownership of its responsibility.
  5. Conversely, information sharing allows other objects to assume responsibilities.

I find following these rules simplifies design decisions in a way that promotes clean design.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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