Qu'est-ce qu'une méthode "usine statique"?
Qu'est-ce qu'une méthode "usine statique"?
Réponses:
Nous évitons de fournir un accès direct aux connexions à la base de données car elles sont gourmandes en ressources. Nous utilisons donc une méthode d'usine statique getDbConnection
qui crée une connexion si nous sommes en dessous de la limite. Sinon, il essaie de fournir une connexion "de rechange", échouant avec une exception s'il n'y en a 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 statique est un moyen d'encapsuler la création d'objets. Sans une méthode de fabrication, vous appelez simplement de la classe constructeur directement: Foo x = new Foo()
. Avec ce modèle, vous à la place appeler la méthode usine: Foo x = Foo.create()
. Les constructeurs sont marqués comme privés, ils ne peuvent donc être appelés que depuis l'intérieur de la classe, et la méthode de fabrique est marquée de static
manière à pouvoir être appelée sans avoir au préalable un objet.
Il y a quelques avantages à ce modèle. La première est que l'usine peut choisir parmi de nombreuses sous-classes (ou implémenteurs d'une interface) et renvoyer cela. De cette façon, l'appelant peut spécifier le comportement souhaité via des paramètres, sans avoir à connaître ou à comprendre une hiérarchie de classe potentiellement complexe.
Comme Matthew et James l'ont souligné, un autre avantage est le contrôle de l'accès à une ressource limitée telle que les connexions. C'est un moyen d'implémenter des pools d'objets réutilisables - au lieu de construire, d'utiliser et de détruire un objet, si la construction et la destruction sont des processus coûteux, il pourrait être plus judicieux de les construire une fois et de les recycler. La méthode d'usine peut renvoyer un objet instancié existant et inutilisé 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 retourner null
s'il est supérieur au seuil supérieur.
Selon l'article sur Wikipedia, 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 une signature donnée . Les usines ne sont pas si contraintes, ce qui signifie que vous pouvez avoir deux méthodes différentes qui acceptent 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 n'est PAS la même que le modèle de méthode d'usine " (c) Java effectif, Joshua Bloch.
Méthode Factory: "Définissez une interface pour créer un objet, mais laissez les classes qui implémentent l'interface décider de la classe à instancier. La méthode Factory permet à une classe de reporter l'instanciation aux 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 effectif, Joshua Bloch. Habituellement, cette méthode se trouve dans une classe particulière.
La différence:
L'idée clé de la méthode d'usine statique est de prendre le contrôle de la création d'objets et de la déléguer du constructeur à la méthode statique. La décision de l'objet à créer est comme dans Abstract Factory prise en dehors de la méthode (dans le cas courant, mais pas toujours). Alors que l'idée clé (!) De la méthode d'usine est de déléguer la décision de l'instance de classe à créer à l'intérieur de la méthode d'usine. Par exemple, l'implémentation Singleton classique est un cas particulier de la méthode d'usine statique. Exemple de méthodes d'usine statique 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();
private Foo(boolean withBar){/*..*/}
public static Foo createWithBar(){return new Foo(true);}
public static Foo createWithoutBar(){return new Foo(false);}
- avoir des noms, contrairement aux constructeurs, qui peuvent clarifier le code.
- vous n'avez pas besoin de créer un nouvel objet à chaque appel - les objets peuvent être mis en cache et réutilisés, si nécessaire.
- peut renvoyer un sous-type de leur type de retour - en particulier, peut renvoyer un objet dont la classe d'implémentation est inconnue de l'appelant. Il s'agit d'une fonctionnalité très précieuse et largement utilisée dans de nombreux frameworks qui utilisent des interfaces comme type de retour des méthodes d'usine statiques.
depuis http://www.javapractices.com/topic/TopicAction.do?Id=21
Tout se résume à la maintenabilité. La meilleure façon de le dire est chaque fois que vous utilisez le new
mot - clé pour créer un objet, vous associez le code que vous écrivez à une implémentation.
Le modèle d'usine vous permet de séparer la façon dont vous créez un objet de ce que vous faites avec l'objet. Lorsque vous créez tous vos objets à l'aide de constructeurs, vous connectez essentiellement le code qui utilise l'objet à cette implémentation. Le code qui utilise votre objet "dépend" de cet objet. Cela peut ne pas sembler être 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'utilisation de l'injection de dépendance, car elles nécessitent beaucoup de code de plaque de chaudière qui s'avère un peu difficile à maintenir. L'injection de dépendances est fondamentalement équivalente aux usines mais vous permet de spécifier comment vos objets sont câblés ensemble de manière déclarative (via la configuration ou les annotations).
Si le constructeur d'une classe est privé, vous ne pouvez pas créer un objet pour la classe à l'extérieur de celle-ci.
class Test{
int x, y;
private Test(){
.......
.......
}
}
Nous ne pouvons pas créer un objet pour la classe ci-dessus à l'extérieur de celui-ci. Vous ne pouvez donc pas accéder à x, y de l'extérieur de la classe. Alors à quoi sert cette classe?
Voici la méthode Answer: FACTORY .
Ajoutez la méthode ci-dessous dans la classe ci-dessus
public static Test getObject(){
return new Test();
}
Vous pouvez donc maintenant créer un objet pour cette classe depuis l'extérieur de celle-ci. Comme la façon dont ...
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 méthode FACTORY
.
Static Factory Method
rapport au constructeur public?
Je pensais que j'apporterais un peu de lumière à ce post sur ce que je sais. Nous avons largement utilisé cette technique dans notre recent android project
. Au lieu de cela, creating objects using new operator
vous pouvez également utiliser static method
pour instancier une classe. Liste des codes:
//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 prennent en charge la création d'objet conditionnelle : chaque fois que vous appelez un constructeur, un objet est créé, mais vous ne le voudrez peut-être pas. supposons que vous vouliez vérifier une condition seulement alors vous voulez créer un nouvel objet. Vous ne créeriez pas une nouvelle instance de Vinoth à chaque fois, à moins que votre condition ne soit remplie.
Un autre exemple tiré de Java efficace .
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Cette méthode traduit une valeur primitive booléenne en une référence d'objet booléen. La Boolean.valueOf(boolean)
méthode nous illustre, elle ne crée jamais d'objet. La possibilité de static factory methods
renvoyer le même objet à partir de répétitions invocations
permet aux classes de maintenir un contrôle strict sur les instances existantes à tout moment.
Static factory methods
est que, contrairement à constructors
, ils peuvent retourner un object
de n'importe quel subtype
type de retour. Une application de cette flexibilité est qu'une API peut renvoyer des objets sans rendre leurs classes publiques. Masquer les classes d'implémentation de cette manière conduit à une API très compacte.
Calendar.getInstance () est un excellent exemple pour ce qui précède, il crée en fonction de la localisation d' un BuddhistCalendar
, JapaneseImperialCalendar
ou par un défaut Georgian
.
Un autre exemple que je pourrais penser est Singleton pattern
, lorsque vous rendez vos constructeurs privés créer une propre getInstance
méthode où 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 une méthode qui résume l'instanciation d'un objet. En général, les usines sont 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 liées, un bon exemple de ceci serait une boîte à outils GUI. Vous pouvez simplement coder en dur les appels aux constructeurs pour les implémentations concrètes de chaque widget, mais si jamais vous vouliez échanger une boîte à outils pour une autre, vous auriez beaucoup d'endroits à changer. En utilisant une usine, vous réduisez la quantité de code que vous devez modifier.
L'un des avantages qui découle de la fabrique statique est que cette API peut renvoyer des objets sans rendre leurs classes publiques. Cela conduit à une API très compacte. En java, cela est réalisé par la classe Collections qui cache environ 32 classes, ce qui rend l'API de collection très compacte.
Une méthode d'usine statique est bonne lorsque vous voulez vous assurer qu'une seule instance va retourner la classe concrète à utiliser.
Par exemple, dans une classe de connexion à une base de données, vous souhaiterez peut-être qu'une seule classe crée la connexion à la base de données, de sorte que 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 regroupement de bases de données, cela se fera également 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 pour laquelle elle est statique est que si vous souhaitez garder une trace de certaines ressources limitées (nombre de connexions de socket ou de poignées de fichier), cette classe peut garder une trace du nombre de sorties et de retours, afin de ne pas épuiser le ressource limitée.
L'un des avantages des méthodes de fabrique statique avec constructeur privé (la création d'objets doit avoir été restreinte pour les classes externes pour garantir que les instances ne sont pas créées en externe) est que vous pouvez créer des classes contrôlées par l'instance . Et les classes contrôlées par l'instance 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, ce qui signifie que vous pouvez vérifier l'égalité des objets avec l' opérateur == au lieu de la méthode equals , selon Effective java.
La capacité des méthodes de fabrique statique à renvoyer le même objet à partir d'appels répétés permet aux classes de maintenir un contrôle strict sur les instances existantes à tout moment. Les classes qui font cela seraient contrôlées par l'instance. Il existe plusieurs raisons d'écrire des classes contrôlées par l'instance. Le contrôle d'instance permet à une classe de garantir qu'il s'agit d'un singleton (élément 3) ou non instanciable (élément 4). En outre, il permet à une classe immuable (article 15) de garantir 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 utiliser l'opérateur == au lieu de la méthode equals (Object), ce qui peut entraîner une amélioration des performances. Les types d'énumération (article 30) offrent cette garantie.
Extrait de Java efficace, Joshua Bloch (article 1, page 6)
statique
Un membre a déclaré avec le mot clé 'statique'.
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».
L'implémentation Java contient les classes d'utilitaires java.util.Arrays et java.util.Collections les deux contiennent des méthodes d'usine statiques , des exemples de celle-ci et comment utiliser:
Arrays.asList("1","2","3")
Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...)
(Seuls quelques exemples, pourraient vérifier javadocs pour des exemples de méthodes mor https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html )
De plus, la classe java.lang.String a de telles méthodes d'usine statiques :
String.format(...), String.valueOf(..), String.copyValueOf(...)