Fabrikmuster
Teil des Abschnitts Objektorientierte Programmierung der Swift-Journey von Coddy. Lektion 43 von 57.
Das Fabrikmuster bündelt die Objekterstellung an einer Stelle. Aufrufer fragen nach dem, was sie benötigen, oft anhand eines Namens oder Typs, und erhalten ein fertiges Objekt, ohne zu wissen, welcher konkrete Typ erstellt wurde:
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)Ausgabe:
9.0
trueDer Aufrufer hängt nur vom Protokoll ab. Das Hinzufügen einer neuen Form bedeutet, die Factory zu ändern, nicht jede Stelle, an der Formen erstellt werden:
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"))Ausgabe:
email: hi
sms: hiStatische Factory-Methoden am Typ selbst sind eine leichtere Form des Musters. Sie geben gängigen Möglichkeiten zum Erstellen eines Werts Namen:
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)Ausgabe:
100
255Ein Enum ohne Fälle, wie etwa ShapeFactory, ist eine gängige Möglichkeit, Factory-Funktionen zu gruppieren: Es kann nicht instanziiert werden und fungiert daher ausschließlich als Namespace.
enum ShapeFactory { // keine cases: kann nicht erstellt werden
static func make(_ kind: String, size: Double) -> (any Shape)? { ... }
}Aufgabe
EinfachSchreibe eine Fabrik für Preispläne. Das Protokoll Plan hat name und price(forUsers:) -> Int. Implementiere Free (0 und nur bis zu 3 Benutzer: darüber beträgt der Preis -1, was „nicht erlaubt“ bedeutet), Team (10 pro Benutzer) und Enterprise (500 pauschal plus 5 pro Benutzer über 100). Vervollständige PlanFactory.make(_:), das den Plan für free, team oder enterprise zurückgibt und andernfalls nil.
Der bereitgestellte Code liest Zeilen im Format plan,users ein und gibt team for 12 users: 120, free does not allow 5 users oder unknown plan: gold aus.
Dein Code gehört in Plan.swift, Free.swift, Team.swift, Enterprise.swift und PlanFactory.swift. main.swift enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
// Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
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)")
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenMethoden und selfInitialisiererKlassen sind ReferenzenRückblick – Bibliotheksausweis4Kapselung
ZugriffskontrolleVon außen schreibgeschütztZustand schützenFehlschlagende InitialisiererRückblick – Bankkonto7Polymorphismus und Generika
PolymorphismusTypumwandlungGenerische FunktionenGenerische TypenZusammenfassung – Shape-Rechner2Strukturen und Werttypen
StrukturenWertsemantikVerändernde MethodenStruktur oder KlasseZusammenfassung – Inventarelement5Vererbung
UnterklassenMethoden überschreibenInitialisierer und superfinal und HierarchienRückblick – Mitarbeiterhierarchie8Standardprotokolle
CustomStringConvertibleEquatableComparableHashableRückblick – Benutzerdefiniertes Sortieren11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Swift-Playground