Dumitrache Andreea Ștefania 321CA
Main packages:
- command: handles all commands
- ticket: manages tickets (Bug, FeatureRequest, UiFeedback)
- milestone: handles milestones
- history: tracks ticket history
- application: handles phase transitions
- user: manages users and their roles
Classes that manage data about users, managers, tickets and milestones are singletons:
UserManager,TicketManager,MilestoneManager,NotificationManager- Ensures only one instance exists
Used factories for creating objects:
BugFactory,FeatureRequestFactory,UiFeedbackFactorycreate each ticket typeTicketFactorypicks the right factory based on typeCommandFactorycreates commands from inputSearchPredicateFactorybuilds filter predicates- Isolates creation logic
For building complex tickets with many fields:
TicketBuilder<T>generic abstractBugBuilder,FeatureRequestBuilder,UiFeedbackBuilder- Each builder sets fields specific to its type (severity for Bug, businessValue for FeatureRequest)
- Handles optional fields
All commands extend Command abstract:
- Each command has
execute()andgetAllowedRoles() - Easy to add new commands
For the notification system:
Observerinterface withnotify(String message)methodUserimplementsObserver(the observers)NotificationManageris the subject that holds the list of observers- Users register with
subscribe()and get notified when needed
For Search command I used filtering strategies:
SearchPredicateFactorybuilds predicates- Each filter is a class (BusinessPriorityPredicate, TypePredicate, etc)
- Can add new filters without modifying existing code
For reports I made GenerateTicketReport abstract:
- Common flow is defined in the template (4 reports use it)
- Subclasses implement
getReport()with their own logic
Userextended by Reporter, Developer, ManagerTicketextended by Bug, FeatureRequest, UiFeedbackTicketBuilder<T>extended by concrete builders
- Commands execute through
execute()without knowing the exact command type - History events handled through
TicketEventinterface
- Private/protected fields with getters and setters
- Singleton managers with getInstance()
- Validations are in classes, not scattered through code
- Abstract classes: Command, User, Ticket, TicketBuilder
- Interfaces: Observer, TicketMetrics, TicketEvent
- Separated what a class does from how it does it
TicketBuilder<T extends TicketBuilder<T>>so each builder returns its own type, not the generic onePredicate<Ticket>,Predicate<Developer>for filteringEnumMapandEnumSetfor enum related data
Used the following features:
- Filter, map for working with tickets and users
- Predicates that can be combined
Supplier<Stream<T>>for reusable streams
EnumMap: for maping enumsEnumSet: for allowed roles in commandsLinkedHashMap: for users in UserManager
Ticket.TicketType,Ticket.BusinessPriorityBug.Severity,Developer.Seniority- Placed them in clases for clearer context
- Single Responsibility:
TicketManageronly manages tickets,NotificationManageronly handles notifications - Open-Closed: can add new filters (predicates) without modifying existing Search code
- Liskov Substitution: any
Ticketsubclass works whereTicketis expected - Interface Segregation: small, specific interfaces like
Observerwhich has justnotify()method - Dependency Inversion: histry tracking depends on the
TicketEventinterface, not on specific event types