Qu'est-ce qu'une méthode "d'usine statique"?
Nous évitons de fournir un accès direct aux connexions de base de données car elles utilisent beaucoup de ressources. Nous utilisons donc une méthode de fabrique statique getDbConnection
qui crée une connexion si nous sommes sous la limite. Sinon, il essaie de fournir une connexion "en réserve", échouant avec une exception s'il n'en existe pas.
public class DbConnection{
private static final int MAX_CONNS = 100;
private static int totalConnections = 0;
private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();
private DbConnection(){
// ...
totalConnections++;
}
public static DbConnection getDbConnection(){
if(totalConnections < MAX_CONNS){
return new DbConnection();
}else if(availableConnections.size() > 0){
DbConnection dbc = availableConnections.iterator().next();
availableConnections.remove(dbc);
return dbc;
}else {
throw new NoDbConnections();
}
}
public static void returnDbConnection(DbConnection dbc){
availableConnections.add(dbc);
//...
}
}
Le modèle de méthode d'usine static est un moyen d'encapsuler la création d'objet. Sans méthode factory, vous appelleriez simplement directement le constructeur de la classe: Foo x = new Foo()
. Avec ce modèle, vous appelleriez plutôt la méthode d'usine: Foo x = Foo.create()
. Les constructeurs sont marqués comme privés. Ils ne peuvent donc être appelés que de l'intérieur de la classe. La méthode de fabrique est marquée comme static
, de sorte qu'elle puisse être appelée sans avoir au préalable d'objet.
Ce modèle présente quelques avantages. La première est que l’usine peut choisir parmi de nombreuses sous-classes (ou les implémenteurs d’une interface) et la renvoyer. Ainsi, l'appelant peut spécifier le comportement souhaité via des paramètres, sans avoir à connaître ou à comprendre une hiérarchie de classes potentiellement complexe.
Comme Matthew et James l'ont souligné, le contrôle de l'accès à une ressource limitée telle que les connexions est un autre avantage. C'est un moyen d'implémenter pools d'objets réutilisables - au lieu de construire, utiliser et détruire un objet, si la construction et la destruction sont des processus coûteux, il serait peut-être plus logique de les construire une fois et de les recycler. La méthode factory peut renvoyer un objet instancié existant, non utilisé s'il en a un, ou en construire un si le nombre d'objets est inférieur à un seuil inférieur, ou lever une exception ou renvoyer null
s'il est supérieur au seuil supérieur.
Selon l'article de Wikipédia, plusieurs méthodes d'usine permettent également différentes interprétations de types d'arguments similaires. Normalement, le constructeur a le même nom que la classe, ce qui signifie que vous ne pouvez avoir qu'un seul constructeur avec un signature donné. Les usines ne sont pas si contraintes, ce qui signifie que vous pouvez avoir deux méthodes différentes acceptant les mêmes types d'arguments:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
et
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
Cela peut également être utilisé pour améliorer la lisibilité, comme le note Rasmus.
REMARQUE! "La méthode d'usine statique estPASidentique à la méthode Usine modèle" (c) Effective Java, Joshua Bloch.
Méthode Factory: "Définit une interface pour créer un objet, mais laisse les classes qui l'implémentent décider de la classe à instancier. La méthode Factory permet à une classe de différer l'instanciation dans des sous-classes" (c) GoF.
"La méthode de fabrique statique est simplement une méthode statique qui renvoie une instance d'une classe." (c) Java efficace, Joshua Bloch. Habituellement, cette méthode est à l'intérieur d'une classe particulière.
La différence:
L'idée clé de la méthode de fabrique statique est de contrôler la création d'objet et de la déléguer du constructeur à la méthode statique. La décision de créer un objet est comme dans Abstract Factory prise en dehors de la méthode (dans le cas courant, mais pas toujours). Tandis que l’idée clé (!) De Factory Method est de déléguer la décision de l’instance de classe à créer dans Factory Method. Par exemple. L'implémentation classique de Singleton est un cas particulier de la méthode fabrique statique. Exemple de méthodes d'usine statiques couramment utilisées:
La lisibilité peut être améliorée par des méthodes d'usine statiques:
Comparer
public class Foo{
public Foo(boolean withBar){
//...
}
}
//...
// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.
à
public class Foo{
public static Foo createWithBar(){
//...
}
public static Foo createWithoutBar(){
//...
}
}
// ...
// This is much easier to read!
Foo foo = Foo.createWithBar();
- avoir des noms, contrairement aux constructeurs, qui peuvent clarifier le code.
- il n’est pas nécessaire de créer un nouvel objet à chaque appel - objets peut être mis en cache et réutilisé, si nécessaire.
- peuvent renvoyer un sous-type de leur type de retour - en particulier, can renvoie un objet dont la classe d'implémentation est inconnue de l'appelant . Il s'agit d'une fonctionnalité très utile et largement utilisée dans de nombreux frameworks qui utilisent des interfaces comme type de retour des méthodes fabriques statiques.
Tout se résume à la maintenabilité. La meilleure façon de le dire est que lorsque vous utilisez le mot clé new
pour créer un objet, vous couplez le code que vous écrivez à une implémentation.
Le modèle d'usine vous permet de séparer la manière dont vous créez un objet de ce que vous faites avec cet objet. Lorsque vous créez tous vos objets à l'aide de constructeurs, vous câblez essentiellement le code qui utilise l'objet pour cette implémentation. Le code qui utilise votre objet est "dépendant de" cet objet. Cela peut ne pas sembler un gros problème en surface, mais lorsque l'objet change (pensez à changer la signature du constructeur ou à sous-classer l'objet), vous devez revenir en arrière et recâbler les choses partout.
Aujourd'hui, les usines ont été largement écartées en faveur de l'injection de dépendance, car elles nécessitent beaucoup de code de plaque chauffante qui s'avère un peu difficile à gérer. L’injection de dépendances est fondamentalement équivalente aux usines, mais vous permet de spécifier la manière dont les objets sont câblés ensemble de manière déclarative (via la configuration ou des annotations).
Si le constructeur d'une classe est privé, vous ne pouvez pas créer d'objet pour la classe à partir de l'extérieur.
class Test{
int x, y;
private Test(){
.......
.......
}
}
Nous ne pouvons pas créer un objet pour la classe ci-dessus de l'extérieur. Vous ne pouvez donc pas accéder à x, y en dehors de la classe. Alors à quoi sert cette classe?
Voici la réponse: USINE méthode.
Ajouter la méthode ci-dessous dans la classe ci-dessus
public static Test getObject(){
return new Test();
}
Alors maintenant, vous pouvez créer un objet pour cette classe en dehors de celle-ci. J'aime le chemin ...
Test t = Test.getObject();
Par conséquent, une méthode statique qui renvoie l'objet de la classe en exécutant son constructeur privé est appelée USINE méthode
.
Je pensais que je vais ajouter un peu de lumière à ce post sur ce que je sais. Nous avons beaucoup utilisé cette technique dans notre recent Android project
. Au lieu de creating objects using new operator
, vous pouvez également utiliser static method
pour instancier une classe. Liste de code:
//instantiating a class using constructor
Vinoth vin = new Vinoth();
//instantiating the class using static method
Class Vinoth{
private Vinoth(){
}
// factory method to instantiate the class
public static Vinoth getInstance(){
if(someCondition)
return new Vinoth();
}
}
Les méthodes statiques supportent la création d'objet conditionnelle : Chaque fois que vous appelez un constructeur, un objet est créé, mais vous ne le souhaitez peut-être pas. Supposons que vous souhaitiez vérifier une condition uniquement pour créer un nouvel objet. Vous ne créeriez pas une nouvelle instance de Vinoth à chaque fois, sauf si votre condition est remplie.
Un autre exemple tiré de Effective Java .
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Cette méthode traduit une valeur de primitive booléenne en une référence d'objet booléen. La méthode Boolean.valueOf(boolean)
nous illustre, elle ne crée jamais d’objet. La capacité de static factory methods
à renvoyer le même objet à partir de invocations
répété permet aux classes de garder un contrôle strict sur les instances existantes à tout moment.
Static factory methods
signifie que, contrairement à constructors
, ils peuvent renvoyer une object
de n’importe quelle subtype
de leur type de retour. Une application de cette flexibilité est qu'une API peut renvoyer des objets sans rendre leurs classes publiques. Cacher les classes d'implémentation de cette manière conduit à une API très compacte.
Calendar.getInstance () est un excellent exemple de ce qui précède. Il crée en fonction de la localisation une BuddhistCalendar
, JapaneseImperialCalendar
ou par défaut une Georgian
.
Un autre exemple que je pourrais penser est Singleton pattern
, où vous faites en sorte que vos constructeurs privés créent une propre méthode getInstance
dans laquelle vous vous assurez qu'il n'y a toujours qu'une seule instance disponible.
public class Singleton{
//initailzed during class loading
private static final Singleton INSTANCE = new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
Une méthode d'usine est une méthode qui extrait l'abstanciation d'un objet. Les usines sont généralement utiles lorsque vous savez que vous avez besoin d'une nouvelle instance d'une classe qui implémente une interface, mais que vous ne connaissez pas la classe d'implémentation.
Ceci est utile lorsque vous travaillez avec des hiérarchies de classes associées. Un bon exemple de ceci serait un toolkit GUI. Vous pouvez simplement coder en dur les appels aux constructeurs pour des implémentations concrètes de chaque widget, mais si vous avez déjà voulu échanger une boîte à outils contre une autre, vous aurez beaucoup d'endroits à changer. En utilisant une usine, vous réduisez la quantité de code à modifier.
L'un des avantages de la fabrique statique est que cette API peut renvoyer des objets sans rendre leurs classes publiques. Cela a conduit à une API très compacte. En Java, ceci est réalisé par la classe Collections qui cache environ 32 classes, ce qui la rend très compacte.
statique
Un membre déclaré avec le mot clé 'static'.
méthodes d'usine
Méthodes qui créent et renvoient de nouveaux objets.
en Java
Le langage de programmation est pertinent pour la signification de «statique» mais pas pour la définition de «usine».
Une méthode de fabrique statique est utile lorsque vous voulez vous assurer qu'une seule instance retournera la classe concrète à utiliser.
Par exemple, dans une classe de connexion à une base de données, vous souhaiterez peut-être ne créer qu'une seule classe pour la connexion à la base de données. Ainsi, si vous décidez de passer de Mysql à Oracle, vous pouvez simplement modifier la logique dans une classe et le reste de l'application utilisez la nouvelle connexion.
Si vous souhaitez implémenter le pooling de bases de données, vous pouvez également le faire sans affecter le reste de l'application.
Il protège le reste de l'application contre les modifications que vous pouvez apporter à l'usine, ce qui est le but.
La raison de son statut statique est que si vous souhaitez suivre certaines ressources limitées (nombre de connexions de socket ou de descripteurs de fichiers), cette classe peut garder une trace du nombre de celles-ci qui ont été distribuées et renvoyées, afin d'éviter d'épuiser les ressources. ressource limitée.
L'un des avantages des méthodes de fabrique statique avec constructeur privé (la création d'objet doit avoir été restreinte pour les classes externes afin de garantir que les instances ne sont pas créées de manière externe) est que vous pouvez créer des classes instance-contrôlée. Et les classes contrôlées par les instances garantissent qu’il n’existe pas deux instances distinctes égales ( a.equals (b) si et seulement si a == b ) pendant l’exécution de votre programme, cela signifie que vous pouvez vérifier l’égalité des objets avec = = opérateur au lieu de égal à méthode, selon Effective Java.
Capacité des méthodes d'usine statique à renvoyer le même objet à partir de des invocations répétées permettent aux classes de garder un contrôle strict sur quelles instances existent à tout moment. Les classes qui font cela sont dites contrôlé par l'instance. Il y a plusieurs raisons d'écrire classes contrôlées par l'instance. Le contrôle d'instance permet à une classe de garantir qu’il s’agit d’un singleton (poste 3) ou non instable (poste 4) . De plus, cela permet à une classe immuable (élément 15) de faire la garantie qu'il n'existe pas deux instances égales: a.equals (b) si et seulement si a == b. Si une classe fait cette garantie, ses clients peuvent alors utiliser l'opérateur == à la place de la méthode equals (Object), ce qui pourrait permettre d’améliorer. performance. Les types énumérés (élément 30) fournissent cette garantie.
De Effective Java, Joshua Bloch (élément 1, page 6)