Author - StudySection Post Views - 62 views
Flyweight Pattern

Flyweight Pattern in Php

The flyweight pattern is the structural pattern of today. Simply put, the Flyweight pattern is used to break down a large domain model into smaller domain models and a collection of smaller object-value classes called flyweights.

Flyweight can be useful when you have a collection of objects that have repeating properties and you want to share these attributes, with the end goal being to save memory usage.

Useful note, before proceeding

Flyweight is extremely unusual in the PHP ecosystem, the benefits it provides are enormously useful in game development, as large amounts of objects are needed. Regardless, below I’m going to cover a game implementation you’re more likely to find in a language like Java or C++.

What is the flyweight pattern?

Flyweights are used to store the common and repetitive data required by the model. These values ​​can be stored in each individual model. However, by using flyweight, you can save memory, because instead of storing the same data everywhere, you just pass around an instance of flyweight, which Points to the same chunk of memory internally.

Flyweight objects should be shared between models, allowing a very small amount of objects to be created, thereby preventing unnecessary memory usage. Sharing objects is a bit different from how the prototype pattern clones objects. Instead, a multiton should be used to make flyweight items and store them internally. Then the second time they are requested, the object in memory is returned.

When to Use the Flyweight Pattern

There are generally no scenarios in PHP when there is a need for a large number of shareable objects. As I mentioned above, the flyweight pattern is very prominent in game development and so the example I provide below will focus on a PHP game implementation.

Rules

  • Flyweight objects should never be created by the client using the new keyword. Instances should always be created using factory class.
  • The factory class should store instances of each flyweight, similar to how a multiton stores a reference to an object in a static attribute.
  • Flyweight attributes that are not shareable (external) between all instances of Flyweight must be supplied by the client and stored inside the Flyweight object.
  • Flyweight attributes that are shareable (intrinsic) must be immutable and set by default to flyweight.
  • The client/controller is responsible for creating the flyweights using the factory class and providing them with the domain model.

Effective use of flyweight patterns can provide memory consumption benefits.
Example:

reload();
}
public function getBaseDamage()
{
return rand(self::MIN_DAMAGE, self::MAX_DAMAGE);
}
public function getEnhancementsDamage()
{
$damage = 0;
foreach($this->enhancements as $enhancement) {
$damage += $enhancement->getDamage();
}
return $damage;
}
public function getDamage()
{
return $this->getBaseDamage() + $this->getEnhancementsDamage();
}
public function reload()
{
$this->ammoRemaining = self::TOTAL_AMMO_IN_PLAMA_SHELL;
}
public function addEnhancement(WeaponFlyweightInterface $enhancement)
{
$this->enhancements[] = $enhancement;
}
}
interface WeaponFlyweightInterface
{
public function getDamage();
}
class PlasmaRifleGrenadeLauncherFlyweight implements WeaponFlyweightInterface
{
const MIN_DAMAGE = 100;
const MAX_DAMAGE = 120;
public function getDamage()
{
return rand(self::MIN_DAMAGE, self::MAX_DAMAGE);
}
}
class PlasmaRifleExplosionFlyweight implements WeaponFlyweightInterface
{
const MIN_DAMAGE = 500;
const MAX_DAMAGE = 1000;
public function getDamage()
{
return rand(self::MIN_DAMAGE, self::MAX_DAMAGE);
}
}
class PlasmaRifleFlyweightFactory
{
private static $instances = [];
public static function factory($flyweight)
{
$className = "PlasmaRifle" . $flyweight . "Flyweight";
if(empty(self::$instances[$className])) {
self::$instances[$className] = new $className();
}
return self::$instances[$className];
}
}
$plasmaRifle = new PlasmaRifle();
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("GrenadeLauncher"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("GrenadeLauncher"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("GrenadeLauncher"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("GrenadeLauncher"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("GrenadeLauncher"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("Explosion"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("Explosion"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("Explosion"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("Explosion"));
$plasmaRifle->addEnhancement(PlasmaRifleFlyweightFactory::factory("Explosion"));
// Fire damage can vary wildly due to the random factor in base damage and flyweight enhancements
echo "Fire 1 Damage: " . $plasmaRifle->getDamage(); # Fire 1 Damage: 3944
echo "Fire 2 Damage: " . $plasmaRifle->getDamage(); # Fire 2 Damage: 4637
echo "Fire 3 Damage: " . $plasmaRifle->getDamage(); # Fire 3 Damage: 4345

If you have skills in PHP programming and you want to enhance your career in this field, a PHP certification from StudySection can help you reach your desired goals. Both beginner level and expert level PHP Certification Exams are offered by StudySection along with other programming certification exams.

Leave a Reply

Your email address will not be published.