Alexandre Vandermonde
Alexandre Vandermonde

Reputation: 579

Encapsulation of array with reference variables

I intend to write a program that simulates particles collisions in one or more dimension. For the 2D case, I would also like to make a GUI that shows the particles.

I have a main class, ParticleCollider, which contains an inner class, Particle, an array of said Particlesas well as some methods for updating the positions and velocities of the particles. The class roughly looks like this:

class ParticleCollider {

     class Particle {
          private double mass;
          private double[] pos;
          //plus some other private class variables
          public Particle(double mass, double[] pos) {
               this.mass = mass; 
               this.pos = pos;
          }
     }

     private Particle[] pArray;

     //Details of constructor are irrelevant
     public ParticleCollider() {

     }

     //Do stuff to particles in pArray, i.e. change their positions and velocitites
     public void update() {
          //For example
          pArray[0].pos[0] = 0;
     }

}

In the graphics class, I want to be able to access the Particles so that I can find their positions and radii for drawing purposes. One way would of course be to add a method getParticlesin ParticleColliderto return the array of Particles, pArray. My question is now if this would be considered a violation of encapsulation. Because the Particleclass has no setters, I cannot change the Particles. Also, because an array hase fixed length, I cannot add any Particles. The only thing I could do, which I guess is pretty bad, is take some Particleand assign it the value of null.

EDIT It has been suggested that I use a List instead of an array and provide an iterator to said List. It would seem to me that this would not solve the encapsulation problem. Regardless, I'm relucant to abandon the array because I need to be able to select a random Particle in the collection of Particles and then iterate it cyclically.

Upvotes: 0

Views: 127

Answers (1)

Jens-Peter Haack
Jens-Peter Haack

Reputation: 1907

How about using this pattern:

    public class Particle {
        // Particle code
    }

    public class Particles implements Iterable<Particle> {
        ArrayList<Particle> myParticles = new ArrayList<Particle>();

        public void add(Particle particle) { myParticles.add(particle); }

        public Iterator<Particle> iterator() {
            return myParticles.iterator();
        }

        // more code on particles
    }

    void bla() {
        Particles particles = new Particles();
        particles.add(new Particle());
        particles.add(new Particle());

        for (Particle particle : particles) {
            System.out.println("P="+particle);
        }
    }

If you want to inhibit the remove() on this iterator you might use this pattern:

    public static class Particles implements Iterable<Particle> {
        ArrayList<Particle> myParticles = new ArrayList<Particle>();

        public void add(Particle particle) { myParticles.add(particle); }

        public Iterator<Particle> iterator() {
            return new Iterator<Particle>() {
                Iterator<Particle> listIterator = myParticles.iterator();

                @Override
                public boolean hasNext() {
                    return listIterator.hasNext();
                }

                @Override
                public Particle next() {
                    return listIterator.next();
                }

                @Override 
                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }

    }

Upvotes: 1

Related Questions