23种设计模式(二)-单一职责模式

单一职责模式

Decorator:装饰者模式

通常情况下,扩展一个类的功能会使用继承方式来实现。
但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。
此时可以使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能。

GoF Decorator模式定义定义:
动态(组合)地给一个对象增加一些额外的职责。
就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数)。

eg1:
/**
 * @author lillcol
 * 2019/6/15-23:56
 */
public abstract class Component { //基础接口
    abstract void operation();
}

class ConcreteComponent1 extends  Component{//具体实现类1

    @Override
    void operation() {
        System.out.println("from ConcreteComponent1 operation");
    }
}

class ConcreteComponent2 extends  Component{//具体实现类2

    @Override
    void operation() {
        System.out.println("from ConcreteComponent2 operation");
    }
}
class Decorator extends Component{ //装饰类
    Component component ;
    public Decorator( Component component){
        this.component=component;
    }
    @Override
    void operation() {
        component.operation();
    }
}

class ConcreteDecoratorA extends  Decorator{//具体装饰类A
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public  void operation(){
        System.out.println("ConcreteDecoratorA operation");
        this.component.operation();
    }

}


class ConcreteDecoratorB extends  Decorator{//具体装饰类B
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    public  void operation(){
        System.out.println("ConcreteDecoratorB operation stag1");
        this.component.operation();
        System.out.println("ConcreteDecoratorB operation stag2" );
    }

}

class DecoratorTest{ //测试
    public static void main(String[] args) {
        ConcreteComponent1 concreteComponent1 = new ConcreteComponent1();
        ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA(concreteComponent1);
        concreteDecoratorA.operation();
        ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB(concreteComponent1);
        concreteDecoratorB.operation();

        System.out.println("------------------------------------------------------------------");

        ConcreteComponent2 concreteComponent2 = new ConcreteComponent2();
        ConcreteDecoratorA concreteDecoratorA2 = new ConcreteDecoratorA(concreteComponent2);
        concreteDecoratorA2.operation();
        ConcreteDecoratorB concreteDecoratorB2 = new ConcreteDecoratorB(concreteComponent2);
        concreteDecoratorB2.operation();

    }
}
//输出结果:
ConcreteDecoratorA operation
from ConcreteComponent1 operation
ConcreteDecoratorB operation stag1
from ConcreteComponent1 operation
ConcreteDecoratorB operation stag2
------------------------------------------------------------------
ConcreteDecoratorA operation
from ConcreteComponent2 operation
ConcreteDecoratorB operation stag1
from ConcreteComponent2 operation
ConcreteDecoratorB operation stag2

Decorator 类图:

Decorator 类图.png

装饰模式主要包含以下角色:

  1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  2. 具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
  3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象==添加或者扩展==的责任。

装饰器的价值在于装饰,他并不影响被装饰类本身的核心功能。在一个继承的体系中,子类通常是互斥的。

  • Bridge:桥模式

模式定义:将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。

某些类具有两个或多个维度的变化,支持不同平台和不同文件格式的媒体播放器。
如何设计播放软件,能播放不同平台和不同文件格式的媒体播放器呢?
如果用继承方式,m 种平台和 n 种文件格式的组合就有 m×n 种,不但对应的子类很多,而且扩展困难。

Bridge类图:

Bridge类图.png

桥接(Bridge)模式包含以下主要角色:
抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
扩展抽象化(RefinedAbstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
具体实现化(ConcreteImplementor)角色:给出实现化角色接口的具体实现。

案例代码:

eg1
/**
 * @author lillcol
 * 2019/6/16-17:17
 */
public class Bridge {
    public static void main(String[] args) {
        ConcreteImplementorA1 concreteImplementorA1 = new ConcreteImplementorA1();
        ConcreteImplementorB2 concreteImplementorB2 = new ConcreteImplementorB2();
        RefinedAbstraction refinedAbstraction = new RefinedAbstraction(concreteImplementorA1, concreteImplementorB2);
        refinedAbstraction.operation();
    }
}

abstract class ImplementorA{ //定义实现接口:平台
    abstract void implementA();
}
class ConcreteImplementorA1 extends ImplementorA{//定义实现类:平台 P1

    @Override
    void implementA() {
        System.out.println("采用平台: ConcreteImplementorA1 P1");
    }
}

class ConcreteImplementorA2 extends ImplementorA{//定义实现类:平台 P2

    @Override
    void implementA() {
        System.out.println("采用平台: ConcreteImplementorA2 P2");
    }
}

abstract class ImplementorB{ //定义实现接口:格式
    abstract void implementB();
}

class ConcreteImplementorB1 extends  ImplementorB{//定义实现类:格式 F1

    @Override
    void implementB() {
        System.out.println("采用格式: ConcreteImplementorB1 F1");
    }
}

class ConcreteImplementorB2 extends  ImplementorB{//定义实现类:格式 F2

    @Override
    void implementB() {
        System.out.println("采用格式: ConcreteImplementorB2 F2");
    }
}

abstract class Abstraction{
    ImplementorA implementorA;
    ImplementorB implementorB;
    Abstraction(ImplementorA implementorA,ImplementorB implementorB){
        this.implementorA=implementorA;
        this.implementorB=implementorB;
    };
    abstract void operation();
}

class RefinedAbstraction extends  Abstraction{

    RefinedAbstraction(ImplementorA implementorA, ImplementorB implementorB) {
        super(implementorA, implementorB);
    }

    @Override
    void operation() {
        implementorA.implementA();
        implementorB.implementB();
    }
}
//输出结果:
采用平台: ConcreteImplementorA1 P1
采用格式: ConcreteImplementorB2 F2

桥接(Bridge)模式的优点是:
由于抽象与实现分离,所以扩展能力强;
其实现细节对客户透明。

缺点是:
由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。

参考文档:
http://c.biancheng.net/view/1364.html
李建忠23中设计模式

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容