設(shè)計模式-結(jié)構(gòu)型模式

結(jié)構(gòu)型模式

類或者對象按照一定布局組成更大的對象。類結(jié)構(gòu)模式采用繼承接口,對象模式采用組合或聚合來組合對象扳躬。
結(jié)構(gòu)型模式中除了適配器外锅减,其余都是對象模式

一糖儡、代理模式

  • 代理模式在客戶端和目標(biāo)對象之間起到中介和保護(hù)作用
  • 優(yōu)點:中介可以擴(kuò)展目標(biāo)對象功能、解耦
  • 缺點:增加代理影響性能怔匣,增加復(fù)雜度
6proxy.png

抽象主題 Abstract Subject

接口或者抽象類定義真實主題和代理對象實現(xiàn)的方法

interface AbstractSubject{
    void request();
}

真實主題 Concrete subject

實現(xiàn)抽象主題具體接口

class ConcreteSubject implement AbstractSubject{
    
    void request(){
        System.out.println("處理請求");
    }
}

代理類 Proxy

提供真實主題相同的接口握联,內(nèi)部包括真實主題的引用,可以訪問每瞒、控制金闽、擴(kuò)展真實主題功能。

class Proxy implements AbstractSubject{
    private ConcreteSubject realSub;
    public request(){
        if(null==realSub){
            realSub=new ConcreteSubject();
        }
        preRequest();
        realSub.request();
        posRequest();
    }
    
    private void preRequest(){
        System.out.println("調(diào)用前");
    }
    
    private void PosRequest(){
        System.out.println("調(diào)用后");
    }
}

調(diào)用類

class  TestProxy{
    
    public static void mian(String[] args){
        Proxy pro=new Proxy();
        pro.request();
    }
}

代理模式擴(kuò)展-動態(tài)代理 DynamicProxy

JDK動態(tài)代理依賴接口剿骨,可以沒有實現(xiàn)類

抽象主題
interface AbstractDynamicSubject{
     void request();
}
真實主題
class DynamicSubject implements AbstractDynamicSubject{
    void request(){
        System.out.println("dynamicSubject");
    }
}
執(zhí)行處理類 InvocationHandler
class MyInvocationHandler implements InvocationHandler{
    @Override
    public Object invok(Object proxy,Method method,Object[] arg) throw ThrowAble{
        System.out.print("testDynamicProxy");
        return null;
    }
}
調(diào)用類
public class TestDynamicProxy{
    
    public static void main(String[] args){
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
        AbstractDynamicSubject proxySubject= (AbstractDynamicSubject) Proxy.newProxyInstance(DynamicSubject.class.getClassLoad(),DynamicSubject
                .class.getInterfaces(),new MyInvocationHandler());
    }
}

二代芜、適配器模式

將類的接口轉(zhuǎn)換為客戶希望的另一個接口,分為類結(jié)構(gòu)模型和對象結(jié)構(gòu)模型浓利,類需要了解組件內(nèi)部細(xì)節(jié)較少使用
適用老的接口使用挤庇,第三方接口匹配

7adapter.png

目標(biāo) target

interface Target{
    void request();
}

(被)適配者 Adaptee

class Adaptee {

void adapteeRequest(){
    
   System.out.println("adaptee");
}
    
}

適配器(類) ClassAdapter

class ClassAdapter extends Adaptee implements Target{
    
    void request(){
        adapteeRequest();
    }
}

對象適配器 ObjectAdapter

class ObjectAdapter implements Target{
    private Adaptee ad;
    
    Public ObjectAdapter(Adaptee cad){
        ad=cad;
    }
    
    void request(){
        ad.adapteeRequest();
    }
}

調(diào)用類

public class TestAdapter{
    public void static main(String[] args){
        Target oba=new ObjectAdapter(new ClassAdapter());
        oba.request();
    }
}

擴(kuò)展,雙向適配器

interface Adpteeinf {
    void adpteeRequest();
}
class TwoObjectAdapter implements Adpteeinf,Target{
    private Adaptee da;
    private Target tg;
    public TwoObjectAdapter(Adaptee cda){
        da=cda;
    }
    public TwoObjectAdapter(Target tga){
        tg=tga;
    }
    
    void request(){
        da.adapteeRequest();
    }
    
    void adapteeRequest(){
        tg.request();
    }
    
}

三荞膘、橋接模式

將抽象和實現(xiàn)分離罚随,使其獨立變化。用組合關(guān)系代替集成關(guān)系來實現(xiàn)羽资,降低了抽象和實現(xiàn)兩個可變維度耦合度淘菩。
當(dāng)一個類有兩種獨立的變化維度,且都需要擴(kuò)展屠升,例如包有顏色潮改、用途兩種維度屬性,且都需要擴(kuò)展變化腹暖。

8bridge.png

實現(xiàn)化角色 implementor

interface Implementor {
    void operation();
}

具體實現(xiàn)化角色 ConcreterImplement

class ConcreteImplement implements Implementor{
    
    void operation(){
        System.out.print("concrete");
    }
}

抽象化角色 Abstraction

abstract Abstraction{
    private Implementor imp;
    
    public Abstraction(Implementor imp){
        this.imp=imp;
    }
    
     void operationImp();
}

擴(kuò)展抽象化角色

class ReAbstraction extends Abstraction{
    public ReAbstraction(Implementor imp){
        super(imp);
    }
    
    public void operationImp(){
         imp.operation();
        System.out.print("Reimp");
    }
}

調(diào)用類

public class TestBridge{
    public static void main(String[] args){
        Implementor imp= new ConcreteImplement();
        ReAbstraction reAb=new ReAbstraction(imp); 
        reAb.operationImp;
    }
}

模式擴(kuò)展

有時橋接模式可與適配器模式聯(lián)合使用汇在。

四、裝飾模式 decorator

不改變現(xiàn)有結(jié)構(gòu)的情況下脏答,動態(tài)增加職責(zé)功能糕殉。最著名的應(yīng)用java中的I/O 設(shè)計
例如,Reader增加緩沖區(qū)

BufferedReader in =new BufferedReader(new FileReader("D:\t.text"));
String s=in.readLine();
9decorator.png

抽象構(gòu)件 Component

定義接口規(guī)范需要附加職責(zé)的對象

interface Component{
    void read();
}

抽象構(gòu)件的實現(xiàn) ConcreteComponent

class ConcreteComponent implements Component{

void read(){
    System.out.println("read");
}
    
}

抽象裝飾 AbstractDecorator

定義需要擴(kuò)展的功能亩鬼,由子類集成實現(xiàn)

abstract Decorator implements Component{
    private Component cp;
    
    public Decorator(Component cp){
        this.cp=cp;
    }
    
    void read(){
        cp.read();
    }
    
}

具體抽象裝飾類 ConcreteDecorator

class ConcreteDecorator extends Decorator{
    
    public ContreteDecorator(Component cp){
    super(cp);
        
    }
    
    void read(){
        super.read();
        addFn();
    }
    
    private addFn(){
        System.out.print("擴(kuò)展功能");
    }
}

五、外觀模式 facade

為多個子系統(tǒng)提供統(tǒng)一個一致的接口阿蝶,方便外部訪問雳锋。
降低了子系統(tǒng)與客戶端直接的耦合,是子系統(tǒng)的變化不會影響調(diào)用羡洁。減少了對象
處理的數(shù)目
新增子系統(tǒng)需要修改外觀類和客戶端玷过,違背了開閉原則。


10facde.png

外觀角色 Facade

對子系統(tǒng)提供統(tǒng)一的接口

class Facade{
    private SubSys1 s1=new SubSys1();
    private SubSys2 s2 =new SubSys2();
    void method(){
    s1.method1();
    s2.method2();
        
    }
}

子系統(tǒng) SubSystem

class SubSys1{
    void method1{
        System.out.println("print1()");
    }
}
class SubSys2{
    void method2{
        System.out.println("print2()");
    }
}

客戶端 TestFacade

class TestFacade{
    public static void main(String[] args){
        
          Facade fe=new Facade();
          fe.method();
    }
}

六筑煮、享元模式 Flyweight

運(yùn)用共享的技術(shù)來有效支撐辛蚊,大量顆粒度的對象復(fù)用。

11flyweight.png

抽象享元角色 Flyweight

規(guī)范要實現(xiàn)的公共接口真仲,非享元通過接口參數(shù)傳入袋马。

interface Flyweight{
    void setUnFlyweight(UnFlyweight uflyweight);
}

具體享元角色 ConcreteFlyweight

class ConcreteFlyweight implements Flyweight{
    private String key;
    public ConcreteFlyweight(String key){
        this.key=key;
    }
    public void setUnflyweight(Unflyweight uflyweight){
        System.out.println("具體享元被調(diào)用");
        System.out.println("非享元信息是"+uflyweight.info());
    }
}

非享元角色 UnsharedFlyweight

class UnshareFlyweight{
    String info;
    public UnshareFlyweight(String info){
        this.info=info;
    }
    public String getInfo(){
        return info;
    }
    pblic void setInfo(String info){
        this.info=info;
    }
}

享元工廠角色 FlyweightFactory

負(fù)責(zé)創(chuàng)建和管理享元角色√徊停客戶請求時返回原有對象或創(chuàng)建新對象飞蛹。

class FlyweightFactory{
    private HashMap<String,Flyweight> flyweights=new HashMap<>();
    
    public getFlyweight(String key){
        Flyweight flyweight=flyweights.get(key);
        if(null==flyweight){
            flyweight =new ConcreteFlyweight(key);
            flyweights.put(key,flyweight);
        } 
        return flyweight;
    }
}

享元模式擴(kuò)展

單純享元模式 、符合享元模式

復(fù)合享元模式 CompositeConcreteFlyweight

public class CompositeCOncreteFlyweight implements Flyweight{
    private List<FLyweight> flyweights=new ArraryList<>();
    
    void setFlyweight(UnFlyweight uFlyweight){
        System.out.println(uFLyweight.getInfo());
    }
    
    public addFlyweight(Flyweight flyweight){
        flyweights.add(flyweight);
    }
    
    public removeFlyweight(Flyweight flyweight){
        flyweights.remove(flyweight);
    }
}

七灸眼、組合模式 Composite

將對象組合成樹狀層次結(jié)構(gòu)的模式卧檐,客戶端可以一致底處理單個對象或組合。分為透明式和安全式

12composite.png

安全式為例:

抽象構(gòu)件 Component

abstract Component{
    
    void operat();
}

樹葉構(gòu)件角色 Leaf

class Leaf implements Component{
    
    void operat(){
        System.out.print("leaf");
    }
}

樹枝構(gòu)件 Composite

class Commposite implements Component{
    private ArrayList<Component> leafs =new ArrayList<>();
    void operat(){
    for(Component leaf:leafs)
        System.out.print("composite");
    }
    
    public addLeaf(Leaf leaf){
        leafs.add(leaf);
    }
    
    pbulic remove(Leaf leaf){
        leafs.remove(leaf);
    }
    public List<Component> getChild(){
    return leafs;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末焰宣,一起剝皮案震驚了整個濱河市霉囚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匕积,老刑警劉巖盈罐,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異闪唆,居然都是意外死亡盅粪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門悄蕾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來票顾,“玉大人,你說我怎么就攤上這事帆调〉旖荆” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵番刊,是天一觀的道長含鳞。 經(jīng)常有香客問我,道長芹务,這世上最難降的妖魔是什么蝉绷? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任鸭廷,我火速辦了婚禮,結(jié)果婚禮上潜必,老公的妹妹穿的比我還像新娘靴姿。我一直安慰自己沃但,他們只是感情好磁滚,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宵晚,像睡著了一般垂攘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淤刃,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天晒他,我揣著相機(jī)與錄音,去河邊找鬼逸贾。 笑死陨仅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铝侵。 我是一名探鬼主播灼伤,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咪鲜!你這毒婦竟也來了狐赡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疟丙,失蹤者是張志新(化名)和其女友劉穎颖侄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體享郊,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡览祖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了炊琉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片展蒂。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖温自,靈堂內(nèi)的尸體忽然破棺而出玄货,到底是詐尸還是另有隱情,我是刑警寧澤悼泌,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布松捉,位于F島的核電站,受9級特大地震影響馆里,放射性物質(zhì)發(fā)生泄漏隘世。R本人自食惡果不足惜可柿,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丙者。 院中可真熱鬧复斥,春花似錦、人聲如沸械媒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纷捞。三九已至痢虹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間主儡,已是汗流浹背奖唯。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留糜值,地道東北人丰捷。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像寂汇,于是被迫代替她去往敵國和親病往。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354