Pattern Factory
Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 43 di 57.
Il pattern factory centralizza la creazione degli oggetti. Chi chiama richiede ciò di cui ha bisogno, spesso tramite nome o tipo, e riceve un oggetto pronto, senza sapere quale tipo concreto è stato creato:
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)Output:
9.0
trueIl chiamante dipende solo dal protocollo. Aggiungere una nuova forma significa modificare la factory, non ogni punto in cui vengono create le forme:
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"))Output:
email: hi
sms: hiI metodi factory statici sul tipo stesso sono una forma più leggera del pattern. Danno un nome ai modi comuni di creare un valore:
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)Output:
100
255Un enum senza casi, come ShapeFactory, è un modo comune per raggruppare funzioni factory: non può essere istanziato, quindi funziona esclusivamente come namespace.
enum ShapeFactory { // nessun caso: non può essere creato
static func make(_ kind: String, size: Double) -> (any Shape)? { ... }
}Sfida
FacileScrivi una factory per i piani tariffari. Il protocollo Plan ha name e price(forUsers:) -> Int. Implementa Free (0, e al massimo 3 utenti: oltre tale soglia il prezzo è -1, ovvero non consentito), Team (10 per utente) ed Enterprise (500 fissi più 5 per ogni utente oltre 100). Completa PlanFactory.make(_:), che restituisce il piano per free, team o enterprise e nil negli altri casi.
Il codice fornito legge righe plan,users e stampa team for 12 users: 120, free does not allow 5 users o unknown plan: gold.
Il tuo codice va in Plan.swift, Free.swift, Team.swift, Enterprise.swift e PlanFactory.swift. main.swift contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
// Codice di input/output fornito: lascialo così com'è
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)")
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiMetodi e selfInizializzatoriLe classi sono riferimentiRiepilogo - Tessera della biblioteca4Incapsulamento
Controllo degli accessiSola lettura dall’esternoProteggere lo statoInizializzatori che possono fallireRiepilogo - Conto bancario7Polimorfismo e tipi generici
PolimorfismoCasting dei tipiFunzioni genericheTipi genericiRipasso - Calcolatore di forme2Struct e tipi valore
Le structSemantica dei valoriMetodi mutantiStruct o classeRiepilogo - Articolo di inventario5Ereditarietà
SottoclassiSovrascrivere i metodiInizializzatori e superfinal e gerarchieRiepilogo - Gerarchia dei dipendenti8Protocolli standard
CustomStringConvertibleEquatableComparableHashableRiepilogo - Ordinamento personalizzato11Progetto: Gestione della biblioteca
Libri e utentiPrestito dei libriEsercitati da solo: Playground Swift