日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

装饰者模式的应用场景

發布時間:2024/4/13 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 装饰者模式的应用场景 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

裝飾者模式(Decorator Pattern)是指在不改變原有對象的基礎之上,將功能附加到對象上,提供了比繼承更有彈性的替代方案(擴展原有對象的功能),屬于結構型模式。裝飾者模式在我們生活中應用也比較多如給煎餅加雞蛋;給蛋糕加上一些水果;給房子裝修等,為對象擴展一些額外的職責。裝飾者在代碼程序中適用于以下場景:

1、用于擴展一個類的功能或給一個類添加附加職責。

2、動態的給一個對象添加功能,這些功能可以再動態的撤銷。

來看一個這樣的場景,上班族白領其實大多有睡懶覺的習慣,每天早上上班都是踩點,于是很多小伙伴為了多賴一會兒床都不吃早餐。那么,也有些小伙伴可能在上班路上碰到賣煎餅的路邊攤,都會順帶一個到公司茶水間吃早餐。賣煎餅的大姐可以給你的煎餅加雞蛋,也可以加香腸。

下面我們用代碼還原一下碼農的生活。首先創建一個煎餅Battercake 類:

public class Battercake {protected String getMsg(){return "煎餅";}public int getPrice(){return 5;}}

創建一個加雞蛋的煎餅BattercakeWithEgg 類

public class BattercakeWithEgg extends Battercake{@Overrideprotected String getMsg() {return super.getMsg() + "+1個雞蛋";}@Override//加一個雞蛋加1塊錢public int getPrice() {return super.getPrice() + 1;} }

再創建一個既加雞蛋又加香腸的BattercakeWithEggAndSausage 類:

public class BattercakeWithEggAndSausage extends BattercakeWithEgg{@Overrideprotected String getMsg() {return super.getMsg() + "+1根香腸";}@Override//加一個香腸加2塊錢public int getPrice() {return super.getPrice() + 2;} }

編寫客戶端測試代碼:

public class BattercakeTest {public static void main(String[] args) {Battercake battercake = new Battercake();System.out.println(battercake.getMsg() + ",總價格:" + battercake.getPrice());Battercake battercakeWithEgg = new BattercakeWithEgg();System.out.println(battercakeWithEgg.getMsg() + ",總價格:" + battercakeWithEgg.getPrice());Battercake battercakeWithEggAndSausage = new BattercakeWithEggAndSausage();System.out.println(battercakeWithEggAndSausage.getMsg() + ",總價格:" + battercakeWithEggAndSausage.getPrice());}}

運行結果沒有問題。但是,如果用戶需要一個加2 個雞蛋加1 根香腸的煎餅,那么用我們現在的類結構是創建不出來的,也無法自動計算出價格,除非再創建一個類做定制。如果需求再變,一直加定制顯然是不科學的。那么下面我們就用裝飾者模式來解決上面的問題。首先創建一個建煎餅的抽象Battercake 類:

public abstract class Battercake {protected abstract String getMsg();protected abstract int getPrice(); }

創建一個基本的煎餅(或者叫基礎套餐)BaseBattercake:

public class BaseBattercake extends Battercake {protected String getMsg(){return "煎餅";}public int getPrice(){return 5;} }

然后,再創建一個擴展套餐的抽象裝飾者BattercakeDecotator 類:

public abstract class BattercakeDecorator extends Battercake {//靜態代理,委派private Battercake battercake;public BattercakeDecorator(Battercake battercake) {this.battercake = battercake;}protected abstract void doSomething();@Overrideprotected String getMsg() {return this.battercake.getMsg();}@Overrideprotected int getPrice() {return this.battercake.getPrice();} }

然后,創建雞蛋裝飾者EggDecorator 類:

public class EggDecorator extends BattercakeDecorator {public EggDecorator(Battercake battercake) {super(battercake);}protected void doSomething() {}@Overrideprotected String getMsg() {return super.getMsg() + "+1個雞蛋";}@Overrideprotected int getPrice() {return super.getPrice() + 1;} }

創建香腸裝飾者SausageDecorator 類:

public class SausageDecorator extends BattercakeDecorator {public SausageDecorator(Battercake battercake) {super(battercake);}protected void doSomething() {}@Overrideprotected String getMsg() {return super.getMsg() + "+1根香腸";}@Overrideprotected int getPrice() {return super.getPrice() + 2;} }

編寫客戶端測試代碼:

public class BattercakeTest {public static void main(String[] args) {Battercake battercake;//路邊攤買一個煎餅battercake = new BaseBattercake();//煎餅有點小,想再加一個雞蛋battercake = new EggDecorator(battercake);//再加一個雞蛋 // battercake = new EggDecorator(battercake);//很餓,再加根香腸battercake = new SausageDecorator(battercake);battercake = new SausageDecorator(battercake);battercake = new SausageDecorator(battercake);battercake = new SausageDecorator(battercake);battercake = new SausageDecorator(battercake);//跟靜態代理最大區別就是職責不同//靜態代理不一定要滿足is-a的關系//靜態代理會做功能增強,同一個職責變得不一樣//裝飾器更多考慮是擴展System.out.println(battercake.getMsg() + ",總價:" + battercake.getPrice());}}

為了加深印象,我們再來看一個應用場景。是否還有小伙伴記得我們上次講個的適配器模式,為了實現新功能與老功能兼容,創建一個新的類繼承已有的類,實現功能擴展,遵循開閉原則。今天我們再用裝飾者模式再來升級一次代碼,同時也做一個更好的對比。先看原來的代碼,Member 類:

public class Member {private String username;private String password;private String mid;private String info;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getMid() {return mid;}public void setMid(String mid) {this.mid = mid;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;} }

ResultMsg 類:

public class ResultMsg {private int code;private String msg;private Object data;public ResultMsg(int code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;} }

ISigninService 接口:

public interface ISigninService {ResultMsg regist(String username, String password);/*** 登錄的方法* @param username* @param password* @return*/ResultMsg login(String username, String password); }

SigninService 實現類:

public class SigninService implements ISigninService {public ResultMsg regist(String username,String password){return new ResultMsg(200,"注冊成功",new Member());}/*** 登錄的方法* @param username* @param password* @return*/public ResultMsg login(String username,String password){return null;} }

創建新的邏輯處理類SigninForThirdService,實現新創建的接口:

public class SiginForThirdService implements ISiginForThirdService {private ISigninService signinService;public SiginForThirdService(ISigninService signinService) {this.signinService = signinService;}public ResultMsg regist(String username, String password) {return signinService.regist(username,password);}public ResultMsg login(String username, String password) {return signinService.login(username,password);}public ResultMsg loginForQQ(String id) {return null;}public ResultMsg loginForWechat(String id) {return null;}public ResultMsg loginForToken(String token) {return null;}public ResultMsg loginForTelphone(String telphone, String code) {return null;}public ResultMsg loginForRegist(String username, String passport) {return null;} }

客戶端測試代碼:

public class DecoratorTest {public static void main(String[] args) {//滿足一個is-aISiginForThirdService siginForThirdService = new SiginForThirdService(new SigninService());siginForThirdService.loginForQQ("sdfasfdasfsf");}}

裝飾者模式最本質的特征是講原有類的附加功能抽離出來,簡化原有類的邏輯。通過這樣兩個案例,我們可以總結出來,其實抽象的裝飾者是可有可無的,具體可以根據業務模型來選擇。

?

總結

以上是生活随笔為你收集整理的装饰者模式的应用场景的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。