Reflection of an object in a 3D world The following is a excerpt from a class that is supposed to represent a reflection of an object in a 3D world, like in a mirror.

After I started I discovered that mirroring is a property of an object, it is either mirrored, or it isn't. Multiple mirrors don't come up with unique objects but just keep flipping from one to the other, with differing rotations.

So with that in mind, how can I re-factor this class, to more suitably deal with the problem?

package au.id.rleach.efficientmultiblocks;

import org.spongepowered.api.util.Axis;

import java.util.EnumMap;
import java.util.LinkedHashSet;
import java.util.Set;

public class Reflexion {
    private final EnumMap&lt;Axis, Boolean&gt; map = new EnumMap&lt;Axis,Boolean&gt;(Axis.class);

    public Reflexion() {
        for(Axis x:Axis.values()){
            map.put(x, false);
        }
    }

    public Reflexion(Axis...axises){
        this();
        for(Axis x : axises){
            map.put(x,true);
        }
    }

    public Reflexion(Reflexion r, boolean x, boolean y, boolean z){
        //^ is xor
        map.put(Axis.X, x ^ r.map.get(Axis.X));
        map.put(Axis.Y, y ^ r.map.get(Axis.Y));
        map.put(Axis.Z, z ^ r.map.get(Axis.Z));
    }

    int getFlip(Axis x){
        return map.get(x) ? -1 : 1;
    }


    static Set&lt;Reflexion&gt; all(){
        return all(new Reflexion());
    }

    static Set&lt;Reflexion&gt; all(Reflexion r){
        Set&lt;Reflexion&gt; out = new LinkedHashSet&lt;Reflexion&gt;();
        //Loop over all values for each axis.
        boolean[] tf = {true, false};
        for(boolean x : tf){
            for(boolean y : tf){
                for(boolean z : tf){
                    out.add(new Reflexion(r, x, y, z));
                }
            }
        }
        return out;
    }
}
From what I understand, you want to make sure that new objects are not created when they are identical to what has been created before.

This is relatively easy, and would include either having a static map or a map inside another object, such as a ReflectionFactory. I'd personally go with ReflectionFactory as I don't like static things when you can avoid them.

Here's an example factory:

public class ReflexionFactory {
    private final Map&lt;Integer, Reflexion&gt; map = new HashMap&lt;&gt;();

    public ReflexionFactory() {
       for (boolean x : tf) {
            for (boolean y : tf) {
                for (boolean z : tf) {
                    Reflexion refl = new Reflexion(this, x, y, z);
                    map.put(refl.getKey(), refl);
                }
            }
        }
    }

    private Reflexion getReflection(int value) {
        return map.get(value);
    }

    Reflexion get(boolean x, boolean y, boolean z) {
        int value = 0;
        if (x) value += 1;
        if (y) value += 2;
        if (z) value += 4;
        return get(value);
    }

    public Set&lt;Reflexion&gt; all(Reflexion r) {
        ...
        for (boolean x : tf) {
            for (boolean y : tf) {
                for (boolean z : tf) {
                    out.add(this.get(x, y, z));
                }
            }
        }
        return out;
    }
}


Some changes in the Reflexion class:

public class Reflexion {

    Reflexion(ReflexionFactory factory, boolean x, boolean y, boolean z) {
        this.factory = factory;
        ...
    }

    public int getKey() {
        int value = 0;
        if (isFlippedX()) value += 1;
        if (isFlippedY()) value += 2;
        if (isFlippedZ()) value += 4;
        return value;
    }
}


There are a few methods I've left up to you to implement, but I hope you get the idea of them.

So what is the most important change?

The idea is to keep a map of all created reflections, stored with an id, and when you previously created the new reflection, you look them up through the factory (which contains the map).

Essentially, this creates what would be called a "Multiton". A class which has a limited amount of instances. (Compared to a "singleton" which only has one instance)