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 类图:
装饰模式主要包含以下角色:
- 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加或者扩展的责任。
装饰器的价值在于装饰,他并不影响被装饰类本身的核心功能。在一个继承的体系中,子类通常是互斥的。
- Bridge:桥模式
模式定义:将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
某些类具有两个或多个维度的变化,支持不同平台和不同文件格式的媒体播放器。
如何设计播放软件,能播放不同平台和不同文件格式的媒体播放器呢?
如果用继承方式,m 种平台和 n 种文件格式的组合就有 m×n 种,不但对应的子类很多,而且扩展困难。
Bridge类图:
桥接(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中设计模式