Essential Software Design Patterns and Testing Techniques
Domain Model
- Shows concepts only: classes, attributes, associations, and multiplicities.
- No methods, no UI, and no controllers are included.
- Purpose: To understand the real-world objects involved in the system.
Use Case Model (Module 6)
- Focuses on Actor ↔ System interaction.
- Uses the Verb + Noun naming convention.
- Format: Defines Actor steps versus System steps.
- Use cases serve as input for sequence diagrams, which inform class diagrams.
UML Class Diagram (Module 7)
- Class Components: Name, attributes, and methods.
- Association: Line connecting classes with multiplicity (1, 0..1, *, 1..*).
- Inheritance: Represented by an open triangle arrow symbol.
- Interface: Indicated by the «interface» stereotype.
- DCD (Design Class Diagram): Explicitly includes methods (unlike the Domain Model).
- Good diagrams exhibit low coupling, high cohesion, and correct GRASP application.
Sequence Diagram
- Shows the order of messages exchanged between objects over time.
- Typical message flow: Actor → Controller → Domain classes.
- Each message defined in the diagram becomes a method in the DCD.
Typical Order Flow Example:
placeOrdercheckAvailabilitycreateOrdercalculateTotalprocessPaymentcompleteOrder
MVC Architecture
- Model:
- Manages business logic and data (e.g., Order, Product classes).
- View:
- Handles the User Interface (UI) and displays data.
- Controller:
- Handles user input, updates the Model, and selects the appropriate View.
Interaction Flow: UI → Controller → Model → View.
GRASP Patterns (Design Rules)
- Information Expert: Assign responsibility to the class that holds the necessary data (e.g., Product checks availability; Order calculates total).
- Creator: The class that aggregates or closely uses another class should be responsible for creating it (e.g., OrderController creates Order).
- Controller: Designate one class to handle system operations (decoupled from the UI).
- Low Coupling: Minimize dependencies between classes.
- High Cohesion: Ensure each class has one focused, well-defined job.
- Polymorphism: Use subclasses to handle variations in behavior.
- Pure Fabrication: Introduce a helper class to maintain the cleanliness of the domain layer.
- Indirection: Use an intermediary (like the Controller) to separate the UI and domain layers.
- Protected Variations: Hide potential changes behind a stable interface.
Good Design Checklist
- The UI must never communicate directly with the domain layer.
- The Controller should not contain business logic.
- Domain classes (e.g., Order, Product) are responsible for calculations and checks.
- Ensure traceability: Use case steps → Sequence Diagram → DCD.
- Avoid bloated controllers (minimize the number of methods per controller).
Software Testing Basics (Module 8)
- Unit Testing:
- Testing a single module or component in isolation.
- Integration Testing:
- Testing how multiple modules interact together.
- System Testing:
- Testing the entire system against functional requirements.
- Acceptance Testing:
- Customer validation to ensure the system meets user needs.
- Regression Testing:
- Rerunning existing tests after changes to ensure no new bugs were introduced.
Testing Goal: Increase confidence in the software and find errors early in the development cycle.
Black-Box Testing Techniques
Based solely on requirements, without knowledge of the internal code structure.
- Equivalence Partitioning (EP): Dividing inputs into valid and invalid groups.
- Boundary Value Analysis (BVA): Testing the edges of input ranges (min, min+1, max-1, max).
- Cause-Effect / Decision Tables: Combining conditions to determine expected outputs.
- State Testing: Testing all defined states and transitions within the system.
White-Box Testing Coverage
Based on internal code structure and implementation details.
- Statement Coverage: Ensuring every line of code is executed.
- Branch Coverage: Ensuring every decision (if/else) evaluates to both true and false.
- Condition Coverage: Ensuring every boolean sub-part of a condition is tested.
- Path / Basis Path Testing: Testing independent execution paths.
Cyclomatic Complexity
A metric for code complexity:
Complexity = E − N + 2 (where E is edges, N is nodes in the control flow graph).
JUnit Quick Recall
Example of testing for exceptions (JUnit 4 syntax):
@Test(expected = Exception.class)Common Assertions:
assertEquals,assertTrue,assertFalse,assertNotNull,assertSame.- Use
@BeforeorsetUp()method for initializing shared test data.
TDD (Test-Driven Development) Cycle
The core process follows the RED → GREEN → REFACTOR loop:
- Write a failing test (RED).
- Write the minimal code required to pass the test (GREEN).
- Improve the code structure without changing behavior (REFACTOR).
English with a size of 6.26 KB