How tawratnibir/online-examination-design-patterns works
1. Project type and runtime
- This is a plain Java console application with no external frameworks, databases, or build tooling.
- The runtime entry point is app.Main, which orchestrates object creation and prints the final exam dashboard to stdout.
2. Top-level architecture
- The system is split into four main boundaries:
- configuration for exam settings
- exam for exam domain types
- question for question abstractions and concrete families
- source for where questions come from
- The design is intentionally pattern-heavy, using Builder, Factory Method, Abstract Factory, and a simple dependency injection / IoC style for question sourcing.
3. Configuration subsystem
- configuration.ExamBuilder builds configuration.ExamConfiguration.
- ExamConfiguration is immutable and holds exam metadata such as title, duration, passing score, negative marking, shuffling, calculator permission, and auto-submit behavior.
- This subsystem is independent of question generation; it defines the exam’s policy and presentation parameters.
4. Exam domain and Factory Method
- exam.Exam is the shared exam abstraction.
- MidtermExam, FinalExam, and PracticeQuiz are concrete exam types.
- exam.factory.ExamFactory is the base factory method layer, with subclasses MidtermExamFactory, FinalExamFactory, and PracticeQuizFactory.
- The exam factory boundary decides which exam type to instantiate, while the rest of the system supplies configuration and questions.
5. Question abstraction layer
- question.Question is the common question model interface/base type.
- Supporting contracts include:
- QuestionFactory for creation
- QuestionRenderer for display formatting
- QuestionEvaluator for scoring/answer checking
- QuestionType for categorization
- This layer isolates the exam system from the details of any particular question family.
6. Abstract Factory for question families
- Concrete question families live in subpackages:
- question.mcq
- question.essay
- question.programming
- question.truefalse
- Each family typically contains four roles:
- a question data class, e.g. MCQQuestion
- a factory, e.g. MCQFactory
- a renderer, e.g. MCQRenderer
- an evaluator, e.g. MCQEvaluator
- The factory acts as the family entry point, creating consistent question objects tied to the right renderer/evaluator behavior.
7. Question source as a dependency boundary
- source.QuestionSource abstracts where question content comes from.
- Implementations are:
- BankQuestionSource for built-in curated questions
- FakerQuestionSource for generated synthetic questions
- ManualQuestionSource for directly supplied questions
- QuestionBank and QuestionFaker support the source implementations.
- Factories receive a QuestionSource instance, which decouples question creation from data origin.
8. How the pieces connect at runtime
- Main chooses an exam factory, creates an exam instance, builds configuration, and selects a question source.
- The exam factory provides the exam shell.
- Question factories use the injected source to create concrete questions of the appropriate family.
- The resulting Question objects are assembled into the exam and then rendered as a dashboard.
9. Concrete demo flow in this repository
- The current sample flow creates a MidtermExam.
- It uses BankQuestionSource.
- It composes a mixed set of question families: MCQ, MCQ, Essay, Programming, and True/False.
- It applies a configuration with title, timing, passing score, and runtime flags such as negative marking, shuffle, calculator access, and auto-submit.
10. Important architectural boundaries for a diagram
- Keep app.Main as the top orchestration node.
- Show configuration as a separate immutable settings path feeding the exam.
- Show exam.factory as the exam-type selection layer.
- Show question as the abstraction layer, with four concrete family branches.
- Show source as an injected dependency into question factories, not a direct dependency of Main on question internals.
- The key direction of dependencies is: Main → factories/configuration → exam/question objects → rendering/output.
Main entry points: Main.java Main · MCQFactory.java MCQ Factory · EssayFactory.java Essay Factory · QuestionType.java Question Type
Components 34
App
Runtime entrypoint and orchestration
- Main · Console entrypoint that assembles the exam flow
src/app/Main.java
Configuration
Immutable exam settings
- Exam Builder · Builds exam configuration objects
src/configuration/ExamBuilder.java - Exam Config · Immutable exam metadata and runtime policy
src/configuration/ExamConfiguration.java
Exam
Exam domain and factory method layer
- Exam · Shared exam model
src/exam/Exam.java - Exam Factory · Base factory for choosing exam variants
src/exam/factory/ExamFactory.java - Midterm Factory · Creates midterm exams
src/exam/factory/MidtermExamFactory.java - Final Factory · Creates final exams
src/exam/factory/FinalExamFactory.java - Practice Factory · Creates practice quizzes
src/exam/factory/PracticeQuizFactory.java - Midterm Exam · Midterm exam variant
src/exam/MidtermExam.java - Final Exam · Final exam variant
src/exam/FinalExam.java - Practice Quiz · Practice quiz variant
src/exam/PracticeQuiz.java
Question
Shared question abstractions and concrete families
- Question · Common question contract
src/question/Question.java - Question Factory · Family-level question creation contract
src/question/QuestionFactory.java - Renderer · Formats questions for display
src/question/QuestionRenderer.java - Evaluator · Checks answers and scores questions
src/question/QuestionEvaluator.java - Question Type · Question classification enum or tag
src/question/QuestionType.java - MCQ · Multiple choice questions and behaviors
src/question/mcq/MCQQuestion.java - Essay · Essay questions and behaviors
src/question/essay/EssayQuestion.java - Programming · Programming questions and behaviors
src/question/programming/ProgrammingQuestion.java - True/False · True/false questions and behaviors
src/question/truefalse/TrueFalseQuestion.java - MCQ Factory · Creates MCQ questions
src/question/mcq/MCQFactory.java - MCQ Renderer · Renders MCQ questions
src/question/mcq/MCQRenderer.java - MCQ Evaluator · Scores MCQ questions
src/question/mcq/MCQEvaluator.java - Essay Factory · Creates essay questions
src/question/essay/EssayFactory.java - Essay Renderer · Renders essay questions
src/question/essay/EssayRenderer.java - Essay Evaluator · Scores essay questions
src/question/essay/EssayEvaluator.java - Prog Factory · Creates programming questions
src/question/programming/ProgrammingFactory.java - Prog Renderer · Renders programming questions
src/question/programming/ProgrammingRenderer.java
Source
Question origin and content providers
- Question Source · Abstracts where question content comes from
src/source/QuestionSource.java - Bank Source · Built-in curated question source
src/source/BankQuestionSource.java - Faker Source · Synthetic question source
src/source/FakerQuestionSource.java - Manual Source · Directly supplied question source
src/source/ManualQuestionSource.java - Question Bank · Curated bank backing the bank source
src/source/QuestionBank.java - Question Faker · Synthetic content generator backing the faker source
src/source/QuestionFaker.java
Connections 33
- Main → Exam Builder: builds · Main builds the exam settings
- Exam Builder → Exam Config: creates · Builder produces immutable configuration
- Main → Midterm Factory: selects · Main chooses the exam variant factory
- Main → Bank Source: chooses · Main selects the question source
- Exam Factory → Exam: abstracts · Factory method layer targets the shared exam type
- Midterm Factory → Midterm Exam: creates · Midterm factory instantiates midterm exam
- Final Factory → Final Exam: creates · Final factory instantiates final exam
- Practice Factory → Practice Quiz: creates · Practice factory instantiates practice quiz
- Main → Exam Factory: uses · Main orchestrates exam creation through the factory layer
- Main → Exam Config: applies · Configuration feeds exam setup
- Main → MCQ Factory: assembles · Main composes question families into the exam
- Main → Essay Factory: assembles · Main composes question families into the exam
- Main → Prog Factory: assembles · Main composes question families into the exam
- Main → True/False: assembles · Main composes question families into the exam
- Question Factory → Question: creates · Question factory contract produces shared question objects
- Question Factory → Question Source: injects · Factories depend on an abstract question source
- Bank Source → Question Source: implements · Curated source conforms to source abstraction
- Faker Source → Question Source: implements · Generated source conforms to source abstraction
- Manual Source → Question Source: implements · Manual source conforms to source abstraction
- Bank Source → Question Bank: reads · Bank source draws from the curated bank
- Faker Source → Question Faker: uses · Faker source uses generator support
- MCQ Factory → MCQ: creates · MCQ factory builds MCQ questions
- MCQ Factory → MCQ Renderer: pairs · MCQ family binds to its renderer
- MCQ Factory → MCQ Evaluator: pairs · MCQ family binds to its evaluator
- Essay Factory → Essay: creates · Essay factory builds essay questions
- Essay Factory → Essay Renderer: pairs · Essay family binds to its renderer
- Essay Factory → Essay Evaluator: pairs · Essay family binds to its evaluator
- Prog Factory → Programming: creates · Programming factory builds programming questions
- Prog Factory → Prog Renderer: pairs · Programming family binds to its renderer
- True/False → Question Type: classified by · True/false questions are one question type
- MCQ → Question Type: classified by · MCQ questions are one question type
- Essay → Question Type: classified by · Essay questions are one question type
- Programming → Question Type: classified by · Programming questions are one question type