Search code examples
javadesign-patternsumlclass-diagramcomposite

Correct usage of composite pattern


I'm currently taking a course in Software Engineering (I have to). We have a whole bunch of tasks which require us to use design patterns in Java. Normally I'm just a PHP developer, so I don't have many skills in Java, which may be a problem.

The specific problem is: We have to use the composite pattern for following problem: Create a mathematic framework to solve terms. The term could be Number (double) or "/", "-" which connect two terms, or "sin" which uses one Term.

I have to create a UML Class Diagram to. Which is this

enter image description here

I'm not sure if this is right. The two main questions I got about my class diagram are:

  1. Is it correct to use value, and first/second for the Composites, because they only have either 1 or 2 Terms, or should I make a list with addmethod and make sure there are exactly 1/2 items in the list?
  2. Should I create another Interface for the Composite Structures (Sin, Divide, Subtract)

Am I doing it right, or did I follow a bad/wrong approach?

Thank you

Bernd


Solution

  • The composite pattern really doesn't place any restrictions on how you represent the children of a composite node. In your case you could either have classes representing unary and binary operations or have separate classes for each operation.

    The second option would look something like:

    interface Term {
        double getValue();
    }
    
    class Constant implements Term {
        private double value;
        public double getValue() {
            return value;
        }
    }
    
    class Divide implements Term {
        private Term numerator;
        private Term denominator;
        public double getValue() {
            return numerator.getValue() / denominator.getValue();
        }
    }
    

    This is probably the closest representation of your UML. In this case there's no advantage in modelling the child terms as a List.

    The other option I mentioned (which I would not recommend) is to have UnaryOperation and BinaryOperation classes and then define and enum for the operations. In this case the operation enumeration would contain the actual calculation logic. I think that's unnecessarily complex for your needs unless you have a large number of operations.