Avatar
Dominik Klapuch:

Ahoj,

mám dvě třídy, které mohou ukládat soubory (obrázky) do databáze a také na pevný disk do nějaké složky. Chci tyto třídy použít zároveň a ukládat jak do databáze, tak na pevný disk - třeba jako zálohu, to je už jedno. Přikládám hirearchii objektů:

interface Storage {
    public function store();
}

class DatabaseStorage implements Storage {
    public function store() {
        //...
    }
}

class FileStorage implements Storage {
    public function store() {
        //...
    }
}

Tak, a teď chci tyto dvě třídy použít zároveň, takže jsem si vytvořil novou třídu.

class ChainStorage implements Storage {
    private $databsaeStorage;
    private $fileStorage;

    public function __construct(Storage $databaseStorage, Storage $fileStorage) {
        $this->databaseStorage = $databaseStorage;
        $this->fileStorage = $fileStorage;
    }

    public function store() {
        $this->databaseStorage->store();
        $this->fileStorage->store();
    }
}

Nicméně, tento způsob se mi nelíbí. Omezuje mě v tom, že pokud bych chtěl přidat další "Storage", musel bych přidat parametr a to mě znechucuje.

Taktéž nechci použít žádný setter typu "setStorage" nebo jinou metodu typu "addStorage", protože by se mi "znehodnotilo" rozhraní.

V jiných programovacích jazycích bych si jednoduše vytvořit List<IStorage> nebo něco v tom smyslu a to předal konstruktoru a poté to v dané metodě store projel cyklem a byl by pokoj, ale jak to udělat tady?

Dostal se někdo do stejné situace, popřípadě, jak jí řešil, či jak byste ji řešili vy?

Odpovědět 15.6.2015 15:15
Kód a data patří k sobě.
Avatar
Odpovídá na Dominik Klapuch
Dominik Klapuch:

Teď mě napadlo, že asi bude nejlepší si vytvořit vlastní iterátor a ten předat. Což se mi jeví asi jako jedno z nejlepší řešení, nad kterým jsem prozatím uvažoval.

Nahoru Odpovědět 15.6.2015 15:32
Kód a data patří k sobě.
Avatar
asanos
Člen
Avatar
Odpovídá na Dominik Klapuch
asanos:

Mrkni se na návrhový vzor Composite.
Mírně poupravíš třídu ChainStorage na:

<?php

class StorageComposite implements Storage{
  protected $storages = array();

  public function addStorage(Storage $stor){
    $this->storages[]= $stor;
  }

  public function store(){
    foreach($this->storages as $stor){
      $stor->store();
    }
  }
}

Pokud jsi něco nepochopil napiš.

  • Možná mám i ve zdrojáku chybu píšu teď od boku. *
Editováno 15.6.2015 15:37
Nahoru Odpovědět  +1 15.6.2015 15:36
Na světě je 10 typů lidí. Ti, kteří rozumí binárce a ti co nerozumí.
Avatar
asanos
Člen
Avatar
asanos:

Nyní můžeš vytvořit stromovou strukturu ve které můžeš vytvořit i více instanci samotného StorageComposite pro jednotlivé úkoly...
Aby jsi v případě kdy budeš chtít ukládat obrázky na disk na vice místech (discích)

________Koreno­vyComposite
________/____­__|_________\
DiskComp____DBCom­p______MailComp
__/_____\____­____|__\___________| \
Disk1__Disk2____DB1___­DB2_____Mail1__Ma­il2

Pak můžeš zavolat Kořenový pro všechny, nebo jen třeba DiskComp pro ukládání na disk a další kombinace... to nechám na tobě ;)

Editováno 15.6.2015 15:55
Nahoru Odpovědět  +1 15.6.2015 15:53
Na světě je 10 typů lidí. Ti, kteří rozumí binárce a ti co nerozumí.
Avatar
Odpovídá na asanos
Dominik Klapuch:

Nad tímto jsem také již přemýšlel, stejně tak nad Decorator. Ale u Composite se bojím, že bych někdy musel psát instanceof, což se mi příčí.

Nahoru Odpovědět  +1 15.6.2015 15:56
Kód a data patří k sobě.
Avatar
asanos
Člen
Avatar
asanos:

instanceof se zdárně vyhýbám, ještě jsem nepsal nic, kde bych to musel využít.
Záleží na tvém návrhu programu... Jiné schůdné řešení než za pomocí Composite mě nenapadá, promiň ;(
Ale kdyby mě ještě něco napadlo, dám vědět. ;)
___
Mám omezený počet odpovědí, u XSS ti odpovím za chvilku ;)

Nahoru Odpovědět 15.6.2015 16:30
Na světě je 10 typů lidí. Ti, kteří rozumí binárce a ti co nerozumí.
Avatar
Dominik Klapuch:

Řešení:

<?php

class ChainStorage implements ImageStorage {
    private $storages = [];

    public function __construct(ImageStorage ...$storages) {
        $this->storages = $storages;
    }

    public function store($image) {
        foreach($this->storages as $storage)
                $storage->store($image);
    }
}
Akceptované řešení
+5 Zkušeností
Řešení problému
Nahoru Odpovědět 5.7.2015 16:52
Kód a data patří k sobě.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.