vendredi 20 mai 2016

Using instances of a class as reference

I need some help on my class design or better said a reference to a common design pattern for a problem.

I am working in the aircraft industry. So far my programming skills are VBA and basic JAVA applications. As an engineer my task is to create CAD Models for fixating components in and on to aircraft kitchens. To ensure a high reusability and to reduce development time I want to create a program which can recommend previous solutions. Basically each aircraft operator can select from a catalog which galleys/kitchens (Monument) it would like to have installed. Inside these Monuments are multiple compartments. Inside a compartment we can install multiple equipment’s/components. I would like to write a program which can tell me "you have installed these components together before -> In this compartment -> in that aircraft for that customer"

I have modeled the compartment, the monuments, and the aircraft. Each class extends form the same class BaseHolder:

public abstract class BaseHolder <I>  {

    private final ArrayList <I> heldItems = new ArrayList<I>();

    public boolean addItem(final I i){
        Objects.requireNonNull(i, "cannot add NULL");
        return heldItems.add(i);
    }

    public boolean removeItem(I i){
        return heldItems.remove(i);
    }

    public boolean contains(I i){
        return heldItems.contains(i);
    }

    public int itemCount(){
        return heldItems.size();
    }

    public boolean isEmpty(){
        return heldItems.isEmpty();
    }

    public void Clear() {
        heldItems.clear();
    }

    protected List<I> getHeldItems(){
        return heldItems;
    }

    public I getElement(int n){
        return heldItems.get(n);
    }
}

public class Aircraft extends BaseHolder<Monument> {
    // code
}

public class Monument extends BaseHolder<Compartment> {

    private String name;

    public Monument (String name){
        this.setName(name);
    }

    // code

    @Override
    public boolean addItem(final Compartment c) {
        Objects.requireNonNull(c, "cannot add NULL");

        if (contains (c) ){
            throw new IllegalArgumentException("Compartment already added!");
        };

        for(Compartment ctmp : getHeldItems()){
            if (ctmp.getName().equals(c.getName() ) ) {
                throw new IllegalArgumentException("Compartment with an identical name already exits");
            }
        }
        return getHeldItems().add(c);
    }

    public Compartment getCompartment(int n){
        return getHeldItems().get(n);
    }

    public Compartment getCompartment(String name){
        for(Compartment ctmp : getHeldItems()){
            if (ctmp.getName().equals(name) ) {
                return ctmp;
            }
        }
        return null;
    }
}

public class Compartment extends BaseHolder<IWeighable>{

    private String name = "";
    private double MAX_LOAD = 0.0;

    public Compartment (String name ,final  double max_load){
        this.setName(name);
        updateMaxLoad(max_load);
    }

    // code

    protected double getTotalLoad(){
        // code
    }

    /**
     * 
     * @param load
     * @throws InvalidParameterException if max load not >= than 0.0
     */
    public void setMaxLoad(final double load){
        if (load >= 0.0){
            this.MAX_LOAD = load;
        } else {
            throw new InvalidParameterException("max load must be greater than 0.0");
        }
    }

    public boolean isOverloaded(){
        return (getTotalLoad() > MAX_LOAD ) ;
    }
}

The problem I am having is that this design seems to have many flaws. Apart from it being rather tedious: getElement(n).getElement(n).getElement(n) Adding elements to a compartment results in all aircrafts using the same compartment, having all the same equipment’s/components installed. As it is the same object in the DB. An instance of the compartment would be need. Cloning the DB Compartment before adding it to an aircraft is no option. I need to be able to change the allowable loads, a change it for all. To resolve this I thought of using some type of “wrapper” class as in:

public class MonumentManager {

    public ArrayList <Monument> monuments = new ArrayList<>();
    public ArrayList <LinkObect> links;

    class LinkObect{
        private Compartment c;

        private IWeighable e;

        LinkObect(Compartment c, IWeighable e){
            this.c = c;
            this.e = e;
        }
    }

    public boolean addMonument(Monument m){
        return monuments.add(m);
    }

    public void addElementToCompartment(IWeighable e, Compartment c){
        boolean known = false; //to check if the passed compartment is known/handeld to/by the MonumentManager
        for (Monument m : monuments){
            if ( m.getCompartment(c.getName() ) != null ) known = true;
        }

        if (known){
            links.add(new LinkObect(c, e));
        } else {
            throw new IllegalArgumentException("Compartment is not inside a managed Monument!");
        }
    }

    public List<Compartment> whereUsed(IWeighable e){
        // TODO 
    }
}

This class might solve the problem but it is feels odd. Can anybody point me in the right direction towards a common design pattern etc. I am reading a book from the local library on design patterns. But it seems to be slightly above me. (as is maybe my task).

Any suggestions / help etc would be highly appreciated.

Aucun commentaire:

Enregistrer un commentaire