This project demonstrates the Flyweight design pattern in a Laravel application. It focuses on efficiently managing and reusing theme and blog configuration data to reduce memory usage and improve performance.
The application showcases a simple blog listing. Each blog has a theme and a configuration. Instead of creating separate objects for each unique combination of theme and configuration, the Flyweight pattern is used. Themes and configurations are stored as "flyweights" and shared among multiple blogs.
App\Contracts\FlyweightInterface
: Defines the interface for all flyweight objects. All Concrete Flyweights implement this interface.App\Flyweights\ThemeFlyweight
: Concrete Flyweight representing a theme. Contains intrinsic state (theme colors).App\Flyweights\BlogConfigurationFlyweight
: Concrete Flyweight representing a blog configuration. Contains intrinsic state (posts per page, allow comments).App\Factories\FlyweightFactory
: Manages the creation and reuse of flyweight objects. It stores existing flyweights in a cache and returns existing instances when possible.config\flyweight.php
: Configuration file storing available themes and blog configurations. This acts as the source of truth for the intrinsic state of our flyweights.App\Models\Blog
: Eloquent model representing a blog. Contains atheme
andconfiguration
attribute, which are keys into theconfig\flyweight.php
configuration.App\Models\Post
: Eloquent model representing a blog post.App\Services\BlogService
: Retrieves and renders blog data using the Flyweight pattern. It uses theFlyweightFactory
to get the appropriate theme and configuration flyweights for a given blog.App\Http\Controllers\BlogController
: Controller that retrieves all blogs and their data and passes it to the view.resources\views\blogs\index.blade.php
: Blade view to display the list of blogs and their associated data.Database\Seeders\BlogSeeder
: Database seeder to populate the database with sample blogs and posts.
-
Configuration Loading: The application loads theme and blog configuration data from the
config/flyweight.php
file. This data serves as the intrinsic state for the flyweights. -
Blog Retrieval: The
BlogController
retrieves all blogs from the database using theBlog
model. -
Flyweight Retrieval and Rendering:
- For each blog, the
BlogService
retrieves the corresponding theme and configuration flyweights from theFlyweightFactory
based on the blog'stheme
andconfiguration
attributes. - The
FlyweightFactory
either returns an existing flyweight instance from its cache or creates a new instance if it doesn't exist. - The
BlogService
passes the blog's ID as extrinsic state to therender()
method of each flyweight. The flyweight combines this extrinsic state with its intrinsic state to produce a rendered string.
- For each blog, the
-
View Rendering: The
BlogController
passes the list of blogs and their rendered data to theblogs.index
view. The view then displays the blog names, theme data, configuration data, and posts.
- Clone the repository.
- Run
composer install
to install the dependencies. - Copy
.env.example
to.env
and configure your database settings. - Run
php artisan key:generate
to generate the application key. - Run
php artisan migrate
to migrate the database. - Run
php artisan db:seed
to seed the database with sample data. - Run
npm install
to install node dependencies. - Run
npm run dev
to build the assets. - Start the development server using
php artisan serve
.
This project includes a docker-compose.yml
file for running the application in a Docker container using Laravel Sail.
- Ensure you have Docker and Docker Compose installed.
- Copy
.env.example
to.env
and configure your database settings (DB_HOST should bemysql
). - Run
./vendor/bin/sail up
to build and start the Docker containers. - Access the application in your browser at
http://localhost
.
The project includes a suite of unit and feature tests to ensure the correctness of the Flyweight implementation. These tests cover:
- Flyweight classes (
ThemeFlyweight
,BlogConfigurationFlyweight
) - FlyweightFactory
- BlogService
- Models (Blog, Post)
- Controller (BlogController)
- Configuration
To run the tests, execute the following command:
sail artisan test --env=testing tests