设计模式

设计模式

除了类本身,设计模式更强调多个类/对象之间的关系和交互过程---比接口/类复用的粒度更大

1.Creational patterns 创建型模式

2.Structural patterns 结构型模式

3.Behavioral patterns 行为类模式

1.1工厂模式

工厂模式就是一个虚拟构造器,为创建对象定义一个接口,让子类决定初始化哪个类

当client不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体创建的实例时,用工厂方法。

定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个类的实例化延迟到其子类。

 

 

 

常规情况下,client直接创建具体对象 Product p = new ProductTwo();

在工厂方法模式下: Product p = new ConcreteTwo().makeObject();

即Abstraction接口的子类ConcreteTwo中的方法makeObject来进行实例化。

 

 

Trace log1 = new Factory1().getTrace();
log1.setDebug(true);
log1.debug( "entering log" );
Trace log2 = new Factory2().getTrace("system");
log2.setDebug(false);
log2.debug("...");

2.1Adaptor 适配器模式

将一个类的接口转换成客户希望的另外一个接口。

Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作。

模式的本质是通过委派或者继承,通过适配器,对现有的代码进行复用,因为现有类代码各种原因导致的无法适配的情况,创建一个接口并进行实现。

 

 

 

 如图,IEmployee类中的方法showHappiness显然无法直接复用Consultant类中的showSmile方法,但如果创建一个接口IEmployee,用类EmployeeAdapter实现接口的showhappiniess方法,同时EmployeeAdapter继承自Consultant,那么EmployeeAdapter就可以利用ShowHappiness方法调用showSmile方法,完成了接口之间的协作,此时EmployeeAdapter相当于一个Adaptor。

public class Consultant { //已存在的类 
    private String name;
    
    public Consultant(String name) {
    this.name = name;
    }

    protected void ShowSmile() {
    System.out.println("Consultant " + this.name + " showed                      smile");
    }
}

public interface IEmployee {//目标接口
    void ShowHappiness();
}

public class EmployeeAdapter extends Consultant implements IEmployee {  //Adapter
    public EmployeeAdapter(String name){
    super(name);
    }

    @Override
    public void ShowHappiness() {
        ShowSmile(); // call the parent Consultant class
    }
}

public class Client {
    public static void main(String[] args){
    IEmployee em = new EmployeeAdapter("Bruno");
        em.ShowHappiness();
    }
}
Result: Consultant Bruno showed smile

这是基于继承的复用,而如果Consultant也是一个接口,那么就可以基于委托复用:

 

新建一个接口,可以将已存在的子类包装起来,面向接口编程就可以隐藏子类

 

 如图,新建一个Shape接口,创建一个子类Rectangle,将display方法委托给LegacyRectangle,这就将内部类型LegacyRectangle与用户隔离了起来,增强了安全性,同时,Adaptor处理了调用接口传入的参数,再委托给LegacyRectangle,这就完成了方法间不兼容的适配。

2.2Decorator

装饰(Decorator)模式的定义: 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

装饰(Decorator)模式的主要优点有: 采用装饰模式扩展对象的功能比采用继承方式更加灵活。 可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。

 

 

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

抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。

抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

抽象构件就是一个接口,具体构件是该接口的子类并添加了最基础的职责,而抽象装饰内都有具体构建的实例,并且实现这些实例的职责,同时,抽象装饰的子类具体装饰可以添加职责,在修饰后就相当于先执行父类的职责(即基础职责),在执行新添加的职责。

decorator的应用

static List<T> unmodifiableList(List<T> lst);

static Set<T> unmodifiableSet( Set<T> set);

static Map<K,V> unmodifiableMap( Map<K,V> map);

3.Behavioral patterns 行为模式

3.1strategy 整体地替换算法

 针对特定任务存在多种算法,调用者需要根据上下文环境动态的选择和切换。

定义一个算法的接口,每个算法用一个类来实现,客户端针对接口编写程序。

 

 

有多种不同的算法来实现同一个任务,但需要client根据需要动态切换算法,而不是写死在代码里

为不同的实现算法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例

 

3.2Template Method

不同的客户端具有相同的算法步骤,但是每个步骤的具体实现不同。

子类中进行各步骤的具体实现

 

比较:3.1委托;3.2继承+重写

3.3Visitor Pattern

对特定类型的object的特定操作(visit),在运行时将二者动态绑定到一起,该操作可以灵活更改,无需更改被visit的类

访问者模式实际做的是创建一个使用其他类中数据的外部类。

如果操作逻辑发生变化,那么我们只需要在visitor实现中进行更改,而不是在所有的item类中进行更改。

本质上:将数据和作用于数据上的某种/些特定操作分离开来。

 

posted @ 2022-06-14 21:46  rtwq  阅读(63)  评论(0)    收藏  举报