Patron Fabrique
Fait partie de la section Programmation orientée objet du Journey Swift de Coddy. Leçon 43 sur 57.
Le modèle fabrique centralise la création des objets. Les appelants demandent ce dont ils ont besoin, souvent par nom ou par type, et reçoivent un objet prêt à l’emploi, sans savoir quel type concret a été construit :
protocol Shape { func area() -> Double }
struct Square: Shape { let side: Double; func area() -> Double { side * side } }
struct Circle: Shape { let r: Double; func area() -> Double { 3 * r * r } }
enum ShapeFactory {
static func make(_ kind: String, size: Double) -> (any Shape)? {
switch kind {
case "square": return Square(side: size)
case "circle": return Circle(r: size)
default: return nil
}
}
}
print(ShapeFactory.make("square", size: 3)!.area())
print(ShapeFactory.make("hexagon", size: 3) == nil)Sortie :
9.0
trueL’appelant ne dépend que du protocole. Ajouter une nouvelle forme signifie modifier la fabrique, et non chaque endroit qui crée des formes :
protocol Notifier { func send(_ m: String) -> String }
struct Email: Notifier { func send(_ m: String) -> String { "email: \(m)" } }
struct SMS: Notifier { func send(_ m: String) -> String { "sms: \(m)" } }
func makeNotifier(for user: String) -> any Notifier {
user.hasSuffix("@mail.com") ? Email() : SMS()
}
print(makeNotifier(for: "ada@mail.com").send("hi"))
print(makeNotifier(for: "555-0100").send("hi"))Sortie :
email: hi
sms: hiLes méthodes d’usine statiques sur le type lui-même constituent une forme plus légère du modèle. Elles donnent des noms aux façons courantes de construire une valeur :
struct Color {
let r: Int, g: Int, b: Int
static func gray(_ v: Int) -> Color { Color(r: v, g: v, b: v) }
static let white = Color(r: 255, g: 255, b: 255)
}
print(Color.gray(100).g)
print(Color.white.b)Sortie :
100
255Un enum sans cas, tel que ShapeFactory, est un moyen courant de regrouper des fonctions de fabrique : il ne peut pas être instancié et fonctionne donc uniquement comme espace de noms.
enum ShapeFactory { // aucun cas : ne peut pas être créé
static func make(_ kind: String, size: Double) -> (any Shape)? { ... }
}Défi
FacileÉcrivez une fabrique pour les plans tarifaires. Le protocole Plan possède name et price(forUsers:) -> Int. Implémentez Free (0, et uniquement jusqu’à 3 utilisateurs : au-delà, le prix est de -1, ce qui signifie que ce n’est pas autorisé), Team (10 par utilisateur) et Enterprise (500 au forfait, plus 5 par utilisateur au-delà de 100). Complétez PlanFactory.make(_:), qui renvoie le plan pour free, team ou enterprise, et nil dans les autres cas.
Le code fourni lit des lignes plan,users et affiche team for 12 users: 120, free does not allow 5 users ou unknown plan: gold.
Votre code doit se trouver dans Plan.swift, Free.swift, Team.swift, Enterprise.swift et PlanFactory.swift. main.swift contient le code d’entrée/sortie fourni et ne peut pas être modifié.
Essayez vous-même
// Code d'entrée/sortie fourni : le garder tel quel
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map(String.init)
let users = Int(p[1])!
guard let plan = PlanFactory.make(p[0]) else {
print("unknown plan: \(p[0])")
continue
}
let price = plan.price(forUsers: users)
print(price < 0 ? "\(plan.name) does not allow \(users) users" : "\(plan.name) for \(users) users: \(price)")
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Classes et objets
Travailler avec des fichiersDéfinir des classesMéthodes et selfInitialiseursLes classes sont des référencesRécapitulatif - Carte de bibliothèque4Encapsulation
Contrôle d’accèsLecture seule depuis l’extérieurProtection de l’étatInitialiseurs pouvant échouerRécapitulatif - Compte bancaire7Polymorphisme et génériques
PolymorphismeConversion de typeFonctions génériquesTypes génériquesRécapitulatif - Calculateur de formes2Structures et types valeur
StructuresSémantique de valeurMéthodes mutantesStructure ou classeRécapitulatif - article d’inventaire5Héritage
Sous-classesRedéfinition des méthodesInitialiseurs et superfinal et hiérarchiesRécapitulatif - hiérarchie des employés8Protocoles standard
CustomStringConvertibleEquatableComparableHashableRécapitulatif - Tri personnalisé11Projet : Gestion de bibliothèque
Livres et membresEmprunter des livresEntraînez-vous par vous-même : Playground Swift