swift - The Decorator Pattern
2015-08-12 22:08
447 查看
装饰者模式:多个类派生于一个基础类,这几个类可以嵌套构造来装饰。
I described the decorator pattern and explained how it can be used to change thebehavior of objects at runtime. The decorator pattern is especially useful when dealing with classesthat cannot
be modified and makes it easy to enhance applications even when working withthird-party or legacy frameworks.
client:
let account =CustomerAccount(name:"Joe");
account.addPurchase(Purchase(product:"Red Hat",
price: 10));
account.addPurchase(Purchase(product:"Scarf",
price: 20));
account.addPurchase(EndOfLineDecorator(purchase:BlackFridayDecorator(purchase:
GiftOptionDecorator(purchase:
Purchase(product:
"Sunglasses", price:25),
options:GiftOptionDecorator.OPTION.GIFTWRAP,
GiftOptionDecorator.OPTION.DELIVERY))));
account.printAccount();
for p inaccount.purchases {
iflet d = p
as?
DiscountDecorator {
println("\(p) has\(d.countDiscounts())
discounts");
}else {
println("\(p) has no discounts");
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pattern:
class Purchase :Printable {
private
let product:String;
private
let price:Float;
init(product:String, price:Float) {
self.product = product;
self.price = price;
}
var description:String {
return
product;
}
var totalPrice:Float {
return
price;
}
}
////
class GiftOptionDecorator :Purchase {
private
let wrappedPurchase:Purchase;
private
let options:[OPTION];
enum OPTION {
case GIFTWRAP;
case RIBBON;
case DELIVERY;
}
init(purchase:Purchase, options:OPTION...) {
self.wrappedPurchase = purchase;
self.options = options;
super.init(product: purchase.description, price: purchase.totalPrice);
}
override
var description:String {
var result =wrappedPurchase.description;
for option
inoptions {
switch (option) {
case .GIFTWRAP:
result ="\(result) + giftwrap";
case .RIBBON:
result ="\(result) + ribbon";
case .DELIVERY:
result ="\(result) + delivery";
}
}
return result;
}
override
var totalPrice:Float {
var result =wrappedPurchase.totalPrice;
for option
inoptions {
switch (option) {
case .GIFTWRAP:
result +=2;
case .RIBBON:
result +=1;
case .DELIVERY:
result +=5;
}
}
return result;
}
}
////
class DiscountDecorator:Purchase {
private
let wrappedPurchase:Purchase;
init(purchase:Purchase) {
self.wrappedPurchase = purchase;
super.init(product: purchase.description, price: purchase.totalPrice);
}
override
var description:String {
return
super.description;
}
var discountAmount:Float {
return
0;
}
func countDiscounts() ->
Int {
var total =
1;
if
let discounter =wrappedPurchase
as?DiscountDecorator {
total += discounter.countDiscounts();
}
return total;
}
}
class BlackFridayDecorator :DiscountDecorator {
override
var totalPrice:Float {
returnsuper.totalPrice -discountAmount;
}
override
var discountAmount:Float {
return
super.totalPrice *0.20;
}
}
class EndOfLineDecorator :DiscountDecorator {
override
var totalPrice:Float {
returnsuper.totalPrice -discountAmount;
}
override
var discountAmount:Float {
return
super.totalPrice *0.70;
}
}
////
import Foundation
class CustomerAccount {
let customerName:String;
var purchases = [Purchase]();
init(name:String) {
self.customerName = name;
}
func addPurchase(purchase:Purchase) {
self.purchases.append(purchase);
}
func printAccount() {
var total:Float =0;
for p
in purchases {
total += p.totalPrice;
println("Purchase\(p), Price\(formatCurrencyString(p.totalPrice))");
}
println("Total due:\(formatCurrencyString(total))");
}
func formatCurrencyString(number:Float) ->String {
let formatter =
NSNumberFormatter();
formatter.numberStyle =NSNumberFormatterStyle.CurrencyStyle;
return formatter.stringFromNumber(number) ??"";
}
}
I described the decorator pattern and explained how it can be used to change thebehavior of objects at runtime. The decorator pattern is especially useful when dealing with classesthat cannot
be modified and makes it easy to enhance applications even when working withthird-party or legacy frameworks.
client:
let account =CustomerAccount(name:"Joe");
account.addPurchase(Purchase(product:"Red Hat",
price: 10));
account.addPurchase(Purchase(product:"Scarf",
price: 20));
account.addPurchase(EndOfLineDecorator(purchase:BlackFridayDecorator(purchase:
GiftOptionDecorator(purchase:
Purchase(product:
"Sunglasses", price:25),
options:GiftOptionDecorator.OPTION.GIFTWRAP,
GiftOptionDecorator.OPTION.DELIVERY))));
account.printAccount();
for p inaccount.purchases {
iflet d = p
as?
DiscountDecorator {
println("\(p) has\(d.countDiscounts())
discounts");
}else {
println("\(p) has no discounts");
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pattern:
class Purchase :Printable {
private
let product:String;
private
let price:Float;
init(product:String, price:Float) {
self.product = product;
self.price = price;
}
var description:String {
return
product;
}
var totalPrice:Float {
return
price;
}
}
////
class GiftOptionDecorator :Purchase {
private
let wrappedPurchase:Purchase;
private
let options:[OPTION];
enum OPTION {
case GIFTWRAP;
case RIBBON;
case DELIVERY;
}
init(purchase:Purchase, options:OPTION...) {
self.wrappedPurchase = purchase;
self.options = options;
super.init(product: purchase.description, price: purchase.totalPrice);
}
override
var description:String {
var result =wrappedPurchase.description;
for option
inoptions {
switch (option) {
case .GIFTWRAP:
result ="\(result) + giftwrap";
case .RIBBON:
result ="\(result) + ribbon";
case .DELIVERY:
result ="\(result) + delivery";
}
}
return result;
}
override
var totalPrice:Float {
var result =wrappedPurchase.totalPrice;
for option
inoptions {
switch (option) {
case .GIFTWRAP:
result +=2;
case .RIBBON:
result +=1;
case .DELIVERY:
result +=5;
}
}
return result;
}
}
////
class DiscountDecorator:Purchase {
private
let wrappedPurchase:Purchase;
init(purchase:Purchase) {
self.wrappedPurchase = purchase;
super.init(product: purchase.description, price: purchase.totalPrice);
}
override
var description:String {
return
super.description;
}
var discountAmount:Float {
return
0;
}
func countDiscounts() ->
Int {
var total =
1;
if
let discounter =wrappedPurchase
as?DiscountDecorator {
total += discounter.countDiscounts();
}
return total;
}
}
class BlackFridayDecorator :DiscountDecorator {
override
var totalPrice:Float {
returnsuper.totalPrice -discountAmount;
}
override
var discountAmount:Float {
return
super.totalPrice *0.20;
}
}
class EndOfLineDecorator :DiscountDecorator {
override
var totalPrice:Float {
returnsuper.totalPrice -discountAmount;
}
override
var discountAmount:Float {
return
super.totalPrice *0.70;
}
}
////
import Foundation
class CustomerAccount {
let customerName:String;
var purchases = [Purchase]();
init(name:String) {
self.customerName = name;
}
func addPurchase(purchase:Purchase) {
self.purchases.append(purchase);
}
func printAccount() {
var total:Float =0;
for p
in purchases {
total += p.totalPrice;
println("Purchase\(p), Price\(formatCurrencyString(p.totalPrice))");
}
println("Total due:\(formatCurrencyString(total))");
}
func formatCurrencyString(number:Float) ->String {
let formatter =
NSNumberFormatter();
formatter.numberStyle =NSNumberFormatterStyle.CurrencyStyle;
return formatter.stringFromNumber(number) ??"";
}
}
相关文章推荐
- Ray Wenderlich的swift教程03--提醒视图控制器UIAlertController
- iOS编程——通过UUID和KeyChain来代替Mac地址实现iOS设备的唯一标示(Swift 优化版)
- Chapter 16 notification iOS 8 -Swift Programming cookBook 读书笔记
- Swift学习笔记(二十六)——扩展
- Swift学习笔记(二十五)——循环结构
- Swift2学习:Swift概览6-泛型
- Swift开发学习(两):Playground
- IOS学习笔记06-Swift语言调试
- Chapter 10 手势 iOS 8 -Swift Programming cookBook 读书笔记
- IOS学习笔记05_2-Swift-命名空间
- CoreData 入门使用 增删改查 swift
- Swift_09属性
- Strings in Swift 2
- swift UI特殊培训38 与滚动码ScrollView
- Swift:闭包(Closures)
- IOS学习笔记05_1-Swift-如何定义类和类的构造方法、重载方法
- 初步swift该研究指出语言(基本数据类型)
- Swift学习笔记之习题
- Ray Wenderlich的swift教程02--引用类型和值类型
- [swift]问号和叹号的区别