好了,昨天我們說(shuō)完了單利模式,趁著現(xiàn)在想寫(xiě)博客就多寫(xiě)幾篇吧.
下面開(kāi)始說(shuō)這個(gè)裝飾模式
裝飾模式其實(shí)還有做成一個(gè)類,一個(gè)類的不斷的繼承,從而實(shí)現(xiàn)功能(裝飾)的加強(qiáng),不過(guò)這樣做太復(fù)雜,
同時(shí)耦合性太高,為了加一次功能就需要一個(gè)新類繼承一次.
我們要不斷的往餅上加肉或者加蛋的,畢竟加了肉和蛋更好吃.哈哈
代碼如下:
//一個(gè)餅的抽閑類abstract class?Bing{
public abstract?double?price();//價(jià)格
?public abstract?String name();//名字
?public void?product(){
System.out.println("生產(chǎn)的餅,名字是"+name()+",價(jià)格是"+price());
}
}
//炊餅class ChuiBing extends Bing {
??? @Override
??? public double price() {
??????? return 1.0;
??? }@Override
??? public String name() {
??????? return "炊餅";
??? }}
//老婆餅class LaopaoBing extends Bing {
??? @Override
??? public double price() {
??????? return 2.6;
??? }@Override
??? public String name() {
??????? return "老婆餅";
??? }}
下面就開(kāi)始給炊餅加蛋了
//炊餅加個(gè)蛋,記為炊餅1class Egg1 extends ChuiBing{
??? //加個(gè)在原來(lái)的基礎(chǔ)上1
??? @Override
??? public double price() {
??????? return super.price()+1.0;
??? }@Override
??? public String name() {
??????? return super.name()+"加了蛋";
??? }}
老板,再加個(gè)蛋
//炊餅1上繼續(xù)加蛋,只能繼續(xù)繼承炊餅1class Egg2 extends Egg1{
??? //加個(gè)在原來(lái)的基礎(chǔ)上1
??? @Override
??? public double price() {
??????? return super.price()+1.0;
??? }@Override
??? public String name() {
??????? return super.name()+"加了蛋";
??? }}
如果再繼續(xù)加肉的話,需要繼續(xù)往上繼承,非常的復(fù)雜.以后的維護(hù)非常的困難.
而如果我們使用裝飾模式,就能夠很方便的添加新的功能(裝飾),得到很多加了肉又加了單的餅了.
//加個(gè)雞蛋的裝飾類class EggDecorate extends Bing{
??? private? Bing b;
??? public EggDecorate(Bing b) {
??????? this.b = b;
??? }@Override
??? public double price() {
?????? return b.price()+0.5;
??? }@Override
??? public String name() {
???? return b.name()+"加了個(gè)雞蛋";
??? }}
//加肉的裝飾類class MeatDecorate extends? Bing{
??? private? Bing b;
??? public MeatDecorate(Bing b) {
??????? this.b = b;
??? }@Override
??? public double price() {
??? return b.price()+1.0;
??? }@Override
??? public String name() {
??????? return b.name()+"加了肉";
??? }}
//測(cè)試方法
public static void main(String[] args){
??? //使用加蛋的來(lái)裝飾炊餅??? EggDecorate ed=new EggDecorate(new ChuiBing());
??? ed.product();//繼續(xù)使用加蛋,來(lái)裝飾剛才的對(duì)象??? EggDecorate decorate = new EggDecorate(ed);
??? decorate.product();}
通過(guò)這種方法,我們就能夠隨意的進(jìn)行裝飾了,得到解耦合的目的,同時(shí),維護(hù)一起也會(huì)更加的方便.
裝飾模式的關(guān)鍵是裝飾類持有基類的對(duì)象,同時(shí)繼承基類,在構(gòu)造函數(shù)中進(jìn)行初始化,表示要進(jìn)行裝飾的對(duì)象,對(duì)這個(gè)對(duì)象進(jìn)行裝飾,繼承基類,就能夠進(jìn)行方法的重寫(xiě),外面就是調(diào)用重寫(xiě)過(guò)的方法,而外面的外用沒(méi)有任何的感覺(jué).
我們只需要對(duì)這個(gè)對(duì)象在原來(lái)的基礎(chǔ)上直接進(jìn)行添加新的裝飾就可以了.從整體上看解耦,同時(shí)也沒(méi)有改變?cè)瓉?lái)對(duì)象
的方法,有點(diǎn)像切面.
關(guān)于裝飾模式,在java的IO中有很好的使用,官方封裝的非常好.
這是java 的IO的部分,下面的BufferedInputStream 就是一個(gè)常用的讀取的緩存包裝類,其構(gòu)造函數(shù)中需要InputStream? 這是讀入的基類,相當(dāng)于上面的Bing,所以能夠?qū)ζ渌囊恍┬枰淖宇愡M(jìn)行包裝.
這就是我的一點(diǎn)理解,如有錯(cuò)誤,請(qǐng)指正.謝謝
2017年8月21日19:33:48