문제

For teaching purposes, I am trying to create a "something useful" example of Flyweight pattern using PHP.

My idea was load some "intrinsic" data from a csv (link) to a pool and allow the user to create "cars" (extrinsic) sharing, if possible, the same flyweight data (car model)

To optimize the memory, I thought that a singleton factory would be a good way to avoid duplicates.

<?php
namespace Flyweight;
class Model { //intrínseco (flyweight)
    private string $name;
    private string $assembler;
    public function __construct(string $name, string $assembler) {
        $this->name = $name;
        $this->assembler = $assembler;
    }
    public function getName(): string {
        return $this->name;
    }
    public function getAssembler(): string {
        return $this->assembler;
    }
}
class FlyweightFactory { //fábrica de flyweight (com singleton)
    private static $singleton;
    private array $flyweights = [];
    private function __construct() {
        $csv = array_map('str_getcsv', file("vehicles.csv"));
        array_walk($csv, function(&$a) use ($csv) {
            $a = array_combine($csv[0], $a);
            $this->flyweights[] = new Model($a['name'], $a['assembler']);
        });
        array_unshift($this->flyweights);
    }
    public static function getInstance(): self {
        if (!self::$singleton) {
            self::$singleton = new self();
        }
        return self::$singleton;
    }
    public function getModel(string $name, string $assembler): Model {
        $modelRetorno = array_filter($this->flyweights,
                fn(Model $model)
                => $model->getName() == $name && $model->getAssembler() == $assembler);
        $modelRetorno = is_array($modelRetorno) ? array_shift($modelRetorno) : null;
        if ($modelRetorno == null) {
            print("cadastrando novo...");
            $modelRetorno = new Model($name, $assembler);
            $this->flyweights[] = $modelRetorno;
        }
        return $modelRetorno;
    }
}
class Vehicle { //extrínsico
    private string $plate;
    private int $year;
    private Model $model;
    public function __construct(string $plate, int $year, Model $model) {
        $this->plate = $plate;
        $this->year = $year;
        $this->model = $model;
    }
    public function getPlate(): string {
        return $this->plate;
    }
    public function getYear(): int {
        return $this->year;
    }
    public function getModel(): Model {
        return $this->model;
    }
}
class VehicleClient { //cliente do flyweight
    private array $vehicles;
    public function register(string $plate, int $year, string $nameModel, string $assembler) {
        $model = FlyweightFactory::getInstance()->getModel($nameModel, $assembler);
        $veiculo = new Vehicle($plate, $year, $model);
        $this->vehicles[] = $veiculo;
    }
    public function getAll(): array {
        return $this->vehicles;
    }
}
$client = new VehicleClient();
$client->register('ABC1234', 1996, "Fiat 147", "FIAT Automobiles S.p.A.");
$client->register('XYB5678', 1998, "Fiat 147", "FIAT Automobiles S.p.A.");
$client->register('NBC9876', 1978, "Gurgel", "Mosantos LTDA");

So,

  1. Is this code a valid Flyweight implementation?
  2. Can I use singleton in a Flyweight factory and still be a valid GoF implementation?
도움이 되었습니까?

해결책

  1. Is this code a valid Flyweight implementation?

Yes, it is a valid Flyweight implementation, although not where I would have expected to see the Flyweight pattern. But for teaching purposes, that is not a problem.

  1. Can I use singleton in a Flyweight factory and still be a valid GoF implementation?

Yes. The GoF patterns were never meant to stand alone. On the other hand, if your aim is to teach what the Flyweight pattern looks like and how it is used, it is better not to mix other concerns/patterns into that lesson. Unless the students are already familiar with the Singleton pattern and can immediately recognize which parts of the code come from that, I think it would be better to leave the Singleton out.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 softwareengineering.stackexchange
scroll top