简体   繁体   中英

How can I add OCL restriction to the class variable?

I'm implementing a Composite design pattern to which a need to add OCL restriction. This is a snippet of a code I'm using.

public abstract class ComplexTerritory implements ITerritory {
    private List<ITerritory> territories = new ArrayList<ITerritory>();
    private Double surfaceArea;
    private String name;

    public ComplexTerritory(String name, Double surfaceArea) {
        this.name = name;
        this.surfaceArea = surfaceArea;
    }

    ...

    public Double getSurfaceArea() {
        Double sArea = 0.0d;
        for (ITerritory ter : territories) {
            sArea += ter.getSurfaceArea();
        }
        return sArea;
    }
}

public class City extends ComplexTerritory {
    public City(String name, Double surfaceArea) {
        super(name, surfaceArea);
    }
}

The OCL restriction is regards to the total surface area. When you call getSurfaceArea() the result of the calculation should match the value that is stored as surfaceArea . How can I do this using OCL? This is what I have come up with, but I'm doubtful that I can use local variable from a method in OCL.

context ComplexTerritory::getSurfaceArea(): Real
  post: self.surfaceArea = sArea

The other idea I had is, that maybe I can iterate over the List using the OCL, something like this:

context ComplexTerritory::getSurfaceArea(): Real
  def: let area : Real = 0.0
       self.territories -> iterate(ter: ITerritory | area = area + ter.getSurfaceArea())
  pre: self.surfaceArea = area

Also, should OCL be used on my abstract class ComplexTerritory or on City class?

In the absence of a metamodel, what you ask is a bit crazy. Assuming you have a metamodel with a ComplexTerritory::surfaceArea property you could complement your Java model with the Complete OCL snippet:

context ComplexTerritory::getSurfaceArea(): Real
  post: result = surfaceArea 

But as already observed it is unclear why you use getSurfaceArea().

Your Java seems fairly free form so I suspect that your OCL will be no more than documentation. Even if you used OCLinEcore to auto-generate your Java code, you would still find that the postcondition was just documentation. (Eclipse OCL only checks the syntax of pre and postconditions).

If you coded

context ComplexTerritory::surfaceArea : Real
 def: territories.surfaceArea->sum()
  

as an OCLinEcore property, the Java would be synthesized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM