门面模式、代理模式、适配器

“接口隔离”模式

  • 在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题,甚至根本无法实现.采用添加一层间接(稳定)接口,来隔离本来相互紧密关联的接口是一种常见的解决方案.
  • 典型模式:
    • Facade(门面模式)
    • Proxy(代理模式)
    • Adapter(适配器)

      门面模式

  • A方案的问题在于组件的客户和组件中各种复杂的子系统有过多的耦合,随着外部客户程序和各个子系统的演化,这种过多的耦合面临着很多变化的挑战.
  • 为子系统中的一组接口提供一个一致(稳定)的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用).

代理模式

  • 动机:在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者,或者系统结构带来很大麻烦.
  • 为其他对象提供一种代理,以控制(隔离、使用接口)对这个对象的访问
  • “增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方案.在面向对象系统中,直接使用某些对象对带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段.

    代码例子

    常规代码设计方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public interface ISubject{
    pub1ic void process();
    }

    public class RealSubject implements ISubject{
    public void process(){
    //.....
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class ClientApp{

    ISubject subject;

    public ClientApp(){
    subject = new RealSubject;
    }

    public void run(){
    //.....
    subject.process();
    //.....
    }

    }

    代理模式改造

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public interface ISubject{
    pub1ic void process();
    }

    public class RealSubject implements ISubject{
    public void process(){
    //.....
    }
    }

1
2
3
4
5
6
public class SubjectProxy implements ISubject{
public void process(){
//对RealSubject的一种间接访问
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ClientApp{

ISubject subject;

public ClientApp(){
subject = new SubjectProxy();
}

public void run(){
//.....
subject.process();
//.....
}

}

适配器模式

  • 动机:在软件系统中,由于应用环境的变化,常常要将”一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些线存对象所不满足的
  • 将一个类的接口转换为客户需要的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //目标接口(新接口)
    public interface ITarget{
    public void process();
    }

    //目标环境(新环境)
    public class TargetLibary{
    public void invoke(ITarget target){
    target.process;
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //现存接口(老接口)
    public interface IAdaptee{
    public void foo(int data);
    public int bar();
    }

    //现存类型
    public class OldClass implements IAdaptee{
    //.....
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//对象适配器
public interface Adapter implements ITarget{//继承
IAdaptee adaptee;//组合

public Adapter(IAdaptee adaptee){
this.adaptee = adaptee;
}

public void process(){
int data = adaptee.bar();
adaptee.foo(data);
}

}

1
2
3
4
5
6
7
8
9
10
11
12
public class ClientApp{
public void run(){
IAdaptee adaptee = new OldClass();
ITarget target = new Adapater(adaptee);

TargetLibary t = new TargetLibary;
t.invoke(target);

}
}


工厂模式

“对象创建”类模式

  • 通过”对象创建模式”绕开new,来避免对象创建new过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.
  • 典型模式:
    • Factory Method(工厂方法)
    • Abstract Factory(抽象工厂)
    • Prototype
    • Builder(建造者模式)

工厂方法

  • 动机:在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化.
  • 提出问题:如何应对这种变化?如何绕开常规的对象创建方法(new),提供一种”封装机制”避免客户程序和这种”具体对象创建工作”的紧耦合?
  • 工厂方法模式定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使得一个 类的实例化延迟(编译时延迟到运行时)到子类.

代码例子

常规代码设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
abstract class ISplitter{
public abstract void split();
}

class BinarySplitter extends ISplitter{
@Override
public void split(){};
}

class TxtSplitter extends ISplitter{
@Override
public void split(){};
}

class PictureSplitter extends ISplitter{
@Override
public void split(){};
}

class VoiceSplitter extends ISplitter{
@Override
public void split(){};
}

1
2
3
4
5
6
7
class client {
public void run(){
//依赖具体的类,编译时创建类
ISplitter splitter = new BinarySplitter();
}
}

工厂方法改造

  • Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系.面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱
  • Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展的策略.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    //抽象类
    abstract class ISplitter{
    public abstract void split();
    }

    class BinarySplitter extends ISplitter{
    @Override
    public void split(){};
    }

    class TxtSplitter extends ISplitter{
    @Override
    public void split(){};
    }

    class PictureSplitter extends ISplitter{
    @Override
    public void split(){};
    }

    class VoiceSplitter extends ISplitter{
    @Override
    public void split(){};
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    //工厂基类
    abstract class SplitterFactory{
    public abstract ISplitter createSplitter();
    }

    //具体工厂
    class BinarySplitterFactory extends SplitterFactory {
    @Override
    public ISplitter createSplitter(){
    return new BinarySplitter();
    }
    }

    class TxtSplitterFactory extends SplitterFactory {
    @Override
    public ISplitter createSplitter(){
    return new TxtSplitter();
    }
    }

    class PictureSplitterFactory extends SplitterFactory {
    @Override
    public ISplitter createSplitter(){
    return new PictureSplitter();
    }
    }

    class VoiceSplitterFactory extends SplitterFactory {
    @Override
    public ISplitter createSplitter(){
    return new VoiceSplitter();
    }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class client {

SplitterFactory factory;

public Client(SplitterFactory factory){
this.factory = factory;
}

public void run(){
//运行时创建对象
ISplitter splitter = factory.createSplitter();
}
}

抽象工厂模式

  • 动机:在软件系统中,经常面临 “一系列相互依赖的对象” 的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class IDBConnection{

    }

    class IDBCommend{

    }

    class IDataReader{

    }

    class MysqlConnection extends IDBConnection{

    }

    class MysqlCommend extends IDBCommend{

    }

    class MysqlDataReader extends IDataReader{

    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
abstract class IDBFactory{
public abstract IDBConnection createDBConnection();
public abstract IDBCommend createDBConnection();
public abstract IDataReader createDataReader();
}

class MysqlDBFactory extends IDBFactory{
@Override
public IDBConnection createDBConnection(){
return new MysqlConnection();
}
@Override
public IDBCommend createDBConnection(){
return new MysqlCommend();
}
@Override
public IDataReader createDataReader(){
return new MysqlDataReader();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class client {

MysqlDBFactory factory;

public Client(SplitterFactory factory){
this.factory = factory;
}

public void run(){
//运行时创建对象
IDBConnection connection = factory.createDBConnection();
IDBCommend connection = factory.createDBCommend();
IDataReader connection = factory.createDataReader();
...
}
}