Question

Le Singleton et les modèles de registre étaient très simples et faciles à comprendre pour moi tout de suite, mais le modèle Factory a été quelque chose que je ne l'ai pas été en mesure d'obtenir mon cerveau pour interpréter encore 100%. Je pense que je pourrais le comprendre maintenant, je l'ai écrit un exemple de code ci-dessous, s'il vous plaît examiner et me dire si cela est l'utilisation correcte du motif usine. L'échantillon est en PHP ...

<?php
 /**
 *   Factory.class.php
 */
class Factory {
    public static $_database;
    public static $_cache;
    public static $_session;

    // Build our User object with all it's dependencies  
    public static function makeUserObject()
    {
        $user = new User();
        $user->setDatabaseObject(self::$_database);
        $user->setCacheObject(self::$_cache);
        $user->setSessionObject(self::$_session);
        return $user;
    }

    // other objects will be here someday......
}

/**
 *  User.class.php
 */
class User
{
    public function __construct() { }

    // inject Database Object
    public function setDatabaseObject($databaseConnectionObject)
    {
        $this->_databaseObject = $databaseConnectionObject;
    }

    // inject Cache Object
    public function setCacheObject($cacheObject)
    {
        $this->_cacheObject = $cacheObject;
    }

    // inject Session Object
    public function setSessionObject($sessionObject)
    {
        $this->_sessionObject = $sessionObject;
    }

    // other methods here for User object...........
}

/**
 *  index.php  Main page that puts it all together
 *  assume that classes are autoloaded into this page already
 */
// Set our Database + Cache + Session objects into the Factory Object
Factory::$_database = new Databse();
Factory::$_cache = new Cache();
Factory::$_session = new Session();

// Create our User object
// The factory class will build the User object and inject all
// it's dependencies for us =)
$user = Factory::makeUserObject();

?>

basiquement la base de données, le cache et les objets de session sont créés (non représenté ici), puis ils sont ajoutés à l'objet Factory, je le peux construire une méthode dans la classe d'usine pour chaque objet qui aura besoin l'une de ces 3 dépendances et je peux définir quels sont ceux qu'ils obtiennent aussi. Cela rend également où les classes individuelles peuvent encore être quelque peu portable que je peux injecter directement là-bas dépendances si je voulais sans l'objet usine. Est-ce son droit? Si cela est vrai, cela semble vraiment utile


Mise à jour # 1

est basé sur ce ici un billet de blog que je lis ici http : //www.potstuck.com/2009/01/08/php-dependency-injection/ ils parlent comme une « usine », j'utilise un registre et beaucoup de gens continuent de me dire de regarder dans une « usine » et tout ce que je lis à ce sujet n'a tout simplement pas cliquer dans ma tête jusqu'à ce que je lis ce artcle mais ressemble ce n'est pas une « usine »?


Mise à jour # 2 De wikipedia http://en.wikipedia.org/wiki/Factory_object Dans la programmation informatique orienté objet, un objet usine est un objet pour créer d'autres objets. Il est une abstraction d'un constructeur, et peut être utilisé pour mettre en œuvre différents régimes d'allocation, comme le singleton. Un objet usine a généralement une méthode pour chaque type d'objet, il est capable de créer. Ces méthodes acceptent des paramètres définissant le cas échéant comment l'objet est créé, puis retourner l'objet créé. objets d'usine sont utilisés dans des situations où se emparer d'un objet d'un type particulier est un processus plus complexe que la simple création d'un nouvel objet. L'objet usine peut décider de créer la classe de l'objet (le cas échéant) de manière dynamique, le retourner à partir d'un pool d'objets, effectuer une configuration complexe sur l'objet, ou d'autres choses.

Alors peut-être c'est un « objet usine » d'une manière ... Après tout

Était-ce utile?

La solution

et CONDENSÉS tendis commentaires ci-dessous de la question ici

Comme d'autres ont dit, ce n'est pas L'usine , simplement parce qu'un modèle avec ce nom n'existe pas. Il est soit un Abstraite ou FactoryMethod , bien que pragmatiquement les gens se réfèrent souvent à l'un ou en disant simplement L'usine et c'est très bien avec moi.

session, Cache et DB sont généralement quelque chose que vous allez initialiser au début de votre flux d'application, donc ce travail est essentiellement bootstrap. J'ai l'impression que vous recherchez est pas tant la création d'objets, mais leur manipulation dans toute l'application. C'est une préoccupation quelque peu différente d'après ce que FactoryWhatever fait.

Comme je l'ai dit dans les commentaires, juste parce que ce nest pas exactement une FactoryWhatever , ne signifie pas que votre code est mauvais. Si cela résout votre problème, il est cool. Mais je pense toujours, ce que vous essayez de faire, par exemple créant et Gestion des ressources à l'exécution est mieux utilisé avec un DI service conteneur.

Si vous ne souhaitez pas utiliser un conteneur DI maintenant pour cela, vous pourriez jeter un oeil à Zend_Application et comment ils bootstrap ressources . Il est une alternative et laisse la possibilité de ajouter des conteneurs DI plus tard.

En fait, tout à fait un grand nombre de sujets dans vos questions précédentes ont été résolus dans Zend Framework déjà, par exemple Les classes Config. Je ne dis pas utiliser ZF, mais vous pouvez le vérifier pour voir comment ils font les choses. Bien sûr, vous pouvez consulter le autres cadres aussi.

Certains sites de modèle avec des exemples PHP:

Autres conseils

C'est le modèle d'usine bien, mais vous pourriez avoir besoin d'une meilleure convention de nommage que juste l'appeler Factory. Il contient également des traces d'injection de dépendance.

Bien que vous puissiez techniquement appeler le modèle d'usine, il est probablement pas une bonne utilisation du motif. Factory est un modèle créationnelle qui encapsule votre code de noms de classe directement référence et la création d'objets comme dans les paramètres du constructeur exact etc. Pour obtenir les meilleurs résultats, garder cela à l'esprit lors de la conception de vos classes et usines.

Par exemple, StackOverflow donne aux utilisateurs différents les droits en fonction de leur score de réputation. Hypothétiquement, il pourrait avoir les types d'utilisateurs suivants:

NewbieUser      [1-100]
BeginnerUser    [101-1000]
AverageJoeUser  [1001-5000]
VeteranUser     [5001-20000]
PowerUser       [20001-50000]
GodModeUser     [50001-100000]

et un utilisateur peut être créé en regardant leur représentant. et l'instanciation de l'objet utilisateur correspondant en faisant référence à la classe directement. Jon Skeet ne semble pas dans une catégorie au cas où vous vous demandez. Voici une mise en œuvre merdique avec instanciation directe:

if(reputation >= 1001 and reputation <= 5000) {
    AverageJoeUser user = new AverageJoeUser();
}

Si plus tard sur la route que nous devions changer les noms de classe ou la façon dont les utilisateurs ont été instanciées, chacun de ces cas où l'objet a été créé devrait être trouvé et changé. Tout à fait beaucoup de travail si vous me demandez. Au lieu de cela, si nous avions utilisé le modèle d'usine ici, le changement irait dans une seule méthode dans la classe usine.

class UserFactory {
    public static User createUser(Integer reputation) {
        ...
    }
}

does't ressemble à une usine pour moi - pourrait être un constructeur à l'envers,? 0)

L'usine est un mode de mise en œuvre et cacher instanciation. Et il y a généralement un ensemble étant fait, mais en quelques mots ....

  public interface IUser
    {
        void DoSomething();
    }

    public class DumbUser : IUser
    {

        public void DoSomething()
        {
            // duh... what should i do?
        }

    }

    public class SmartUser : IUser
    {

        public void DoSomething()
        {
            // calclulating prime numbers while baking bread
        }

    }


    public class UserFactory
    {
        public static IUser CreateUser()
        {
            Random r = new Random(Environment.TickCount);

            return r.Next(10) > 5 ? (IUser) new SmartUser() : new DumbUser();
        }
    }

    public class YourProgram
    {
        public void Run()
        {
            IUser user = UserFactory.CreateUser();
            user.DoSomething();
        }
    }

Comme il semble que vous voulez simplement créer un utilisateur, je ne vois pas la nécessité d'un facteur abstrait, désormais appelée simplement usine. L'idée des usines est de créer des objets qui mettent en œuvre une certaine interface. Vous voudriez pouvoir instancier deux implémentations différentes de la même interface. Le point est que vous devrez peut-être créer ces objets à plusieurs reprises, et changig il de ObjectA à objectB tout le code est lourd. L'échange de l'usine est facile, car il est souvent un singleton.

L'idée de la méthode d'usine est liée aux cadres: Vous voulez créer une utilisation dans un code-cadre, mais la mise en œuvre de l'utilisateur réel est dans les classes dérivées, à savoir il y a des utilisateurs de votre cadre écrire leur propre application - qui est quand vous avez besoin pour indiquer à l'utilisateur de vous cadre « créer un objet utilisateur maintenant », qui est un appel à la méthode de l'usine. L'utilisateur doit mettre en œuvre. Il est aussi appelé un Contstructor virtuel selon GoF.

Le constructeur est généralement utilisé quand il y a des représentations différentes de l'objet, ce qui est pas vraiment le cas ici. A mes yeux, cache, base de données et une session pourraient être mises en œuvre singletons, facilitant ainsi les complexités impliquées. Dans le cas contraire, je suggère d'utiliser un ServiceLocator qui vous permet de GetDatabase, GetSession, etc. Ensuite, vous auriez à passer le localisateur pour objet utilisateur (et bien d'autres objets) sur la création. L'avantage est que ce localisateur peut être réutilisé dans différentes classes.

ressemble plus comme le modèle Builder pour moi. Quel modèle usine, vous avez fait dire, AbtractFactory ou FactoryMethod? Cependant, ils traitent tous les deux avec l'héritage et vous codez assemble juste un objet « complexe ».

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top