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中设计模式

posted @ 2019-07-04 00:18  lillcol  阅读(235)  评论(0编辑  收藏  举报