Skip to content
Keshan W edited this page Nov 22, 2024 · 16 revisions

Class Diagram

Gopher's Class Diagram for Autograder

SOLID Principles

The SOLID principles are design guidelines that ensures software is maintainable, scalable, and flexible. It consist of five principles which address different aspects of object-oriented design to improve code quality.


Single Responsibility Principle:

The SRP asserts that a class should have only one reason to change, meaning it should have only one responsibility. This system adheres to the SRP by ensuring that each class handles a distinct task. For example, the SubmissionOrganizer class fulfills a singular responsibility, with the method public static List<String> organizeSubmissions(String output) specifically designed to organize student submissions.


Open/Closed Principle:

The OCP states that classes should be open for extension but closed for modification. The system follows this principle by using interfaces, which allow for new functionality to be added without modifying existing code. A prime example is the MarkSchemeLoaderStrategy interface, which can facilitate parsing of the mark scheme from different file formats, such as a .json file.


Liskov Substitution Principle:

The LSP asserts that objects of a superclass should be replaceable with objects of its subclasses without affecting the application's functionality. This principle is upheld throughout the system particularly in the case of the GradeTemplate abstract class. Any subclass of GradeTemplate can replace a GradeTemplate object without disrupting the program's behavior, ensuring correctness and maintaining expected functionality.


Interface Segregation Principle:

The ISP emphasizes that interfaces should not force subtypes to implement methods they do not use. The interfaces within this system are modular and focused, avoiding unnecessary generalizations and ensuring subtypes only implement methods they require. For example, TestRunner interface declares only the essential method runAllTests(), preventing unnecessary methods from being implemented by subclasses.


Dependency Inversion Principle:

The DIP states that low level modules should not depend on high level modules but rather they should both depend on abstractions. All implemented modules depend on interfaces which acts as the abstraction between module levels. Additionally, the DIP states that abstractions should not depend on details but details should depend on abstractions. The system's interfaces are carefully defined to specify necessary behaviors and the corresponding implementations must adhere to these abstractions.

Java docs: Java Documentation

Clone this wiki locally