This is an assignment to the Software Architecture class at the Technische Hochschule Nürnberg.
This assignment covers an advanced topic of generics: bounds on type parameters and wildcards. Bounds describe type constraints of generic classes or methods that allow to balance type safety with flexibility of use.
- Create a fork of this repository (button in the right upper corner)
- Clone the project (get the link by clicking the green Clone or download button)
- Import the project to your IDE (remember the guide in assignment 1)
- Validate your environment by running the tests from your IntelliJ and by running
gradle test
on the command line.
First, create the model for this assigment:
- Create the
enum
PlantColor - Implement the
abstract
class Plant - Implement the child classes Flower and Shrub
Remarks:- A shrub is always green; a flower may be any color but green (handle a wrong value in the constructor)
- Flowers compare to each other by height
- All good data classes should always implement
equals
andhashCode
, ideally alsotoString
.
- Create tests to ensure that your model classes are correct (e.g. green flowers won't work)
Implement a PlantBed
which manages a list of plants (use SimpleList<T>
).
A PlantBed
may contain any subclass of Plant
but nothing else!
Use appropriate bounds when declaring the generic class.
Remarks: The method getPlantsByColor
is very easy to implement if you think of the filter
method of the SimpleList
!
Remember to create tests for nearly every line you code!
Last but not least we'll look at the PECS (Producer Extends Consumer Super) principle.
Implement a method repot
that removes plants from one bed and inserts it in another.
Make sure that you can repot from a flower bed to a plant bed, but not vice versa.
- Add a
remove
function toPlantBed
- Implement the utility method
repot
in a utility classPlantBedUtility
, use the appropriate bounds. Why should this class be declaredabstract
and have aprivate
constructor?
Remark: the above UML diagram for the utility method does not include any bounds but you need some (PECS!) -- the compiler is unable to capture the types if you implement the method strictly as described in the UML!