- Created .gitignore to exclude logs and build artifacts. - Added Dockerfile and docker-compose.yml for containerized deployment. - Implemented a video player following SOLID principles with classes for video source, audio control, and volume meter. - Introduced interfaces for audio, video source, and volume meter to ensure adherence to Interface Segregation Principle. - Developed main entry point and HTML structure for the video player application. - Included TypeScript configuration and package.json for project dependencies.
3.5 KiB
3.5 KiB
SOLID Principles Implementation
This project has been refactored to follow the SOLID principles of Object-Oriented Programming.
Overview
The codebase is organized into:
- Interfaces (
src/interfaces/) - Define contracts following Interface Segregation Principle - Classes (
src/classes/) - Implementations following Single Responsibility Principle - Main (
src/main.ts) - Entry point that uses Dependency Inversion Principle
SOLID Principles Applied
1. Single Responsibility Principle (SRP)
Each class has one reason to change:
VideoSource: Only responsible for managing video source elementsVideoSeekController: Only responsible for seeking operationsAudioController: Only responsible for audio control (mute/unmute)VideoPlayer: Only responsible for orchestrating the components
2. Open/Closed Principle (OCP)
The system is open for extension but closed for modification:
- New video source types can be added by implementing
IVideoSource - New seeking strategies can be added by implementing
IVideoSeekController - New audio control mechanisms can be added by implementing
IAudioController - The
VideoPlayerclass doesn't need modification when adding new implementations
3. Liskov Substitution Principle (LSP)
Any implementation of an interface can be substituted without breaking functionality:
- Any class implementing
IVideoSourcecan replaceVideoSource - Any class implementing
IVideoSeekControllercan replaceVideoSeekController - Any class implementing
IAudioControllercan replaceAudioController
4. Interface Segregation Principle (ISP)
Interfaces are small and focused on specific behaviors:
IVideoSource: Only methods related to video source managementIVideoSeekController: Only methods related to seekingIAudioController: Only methods related to audio controlIVideoPlayer: High-level interface for the complete player
5. Dependency Inversion Principle (DIP)
High-level modules depend on abstractions, not concrete implementations:
VideoPlayerdepends on interfaces (IVideoSource,IVideoSeekController,IAudioController)- Concrete implementations are injected via constructor
- This allows easy testing and swapping of implementations
Architecture Benefits
- Testability: Each component can be tested in isolation
- Maintainability: Changes to one component don't affect others
- Extensibility: New features can be added without modifying existing code
- Flexibility: Implementations can be swapped easily (e.g., for testing or different behaviors)
Example: Adding a New Feature
To add a new video source type (e.g., DASH streaming):
- Create a new class
DashVideoSourceimplementingIVideoSource - Use it in
VideoPlayerconstructor:this.videoSource = new DashVideoSource() - No other code needs to change!
File Structure
src/
├── interfaces/
│ ├── IVideoSource.ts # Video source contract
│ ├── IVideoSeekController.ts # Seeking contract
│ ├── IAudioController.ts # Audio control contract
│ └── IVideoPlayer.ts # Main player contract
├── classes/
│ ├── VideoSource.ts # Video source implementation
│ ├── VideoSeekController.ts # Seeking implementation
│ ├── AudioController.ts # Audio control implementation
│ └── VideoPlayer.ts # Main player orchestrator
└── main.ts # Application entry point