swift - The Decorator Pattern

装饰者模式:多个类派生于一个基础类,这几个类可以嵌套构造来装饰。

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) ??"";

}

}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...