ivaneye.com

语言与模式-10装饰模式

意图

动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

适用性

Java实现

JavaIO库的使用可能如下

BufferedInputStream bi = new BufferedInputStream(new FileInputStream(filename));

我们都知道FileInputStream是用来读取文件的,BufferedInputStream是提供了缓存的能力。我们分别看下他们的源代码

public class BufferedInputStream extends FilterInputStream
...
public class FilterInputStream extends InputStream
...
public class FileInputStream extends InputStream
...

BufferedInputStream继承了FilterInputStream,FilterInputStream和FileInputStream一样都继承自InputStream.

可以看出InputStream是公共父类。

FilterInputStream是装饰类的公共父类,看看FilterInputStream的源代码就知道了,他只是做了简单的方法委托。

BufferedInputStream继承了FilterInputStream,并添加了缓存的方法(其实就是用一个字节数组保存字节,一次性读出)。

语言与模式-09组合模式

意图

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。

适用性

Java实现

public interface Node {
    void check();
    void add(Node node) throws Exception;
    void remove(Node node) throws Exception;
}
public class ParentNode implements Node {
    private List<Node> list = new ArrayList<Node>();
    public void check() {
        System.out.println("ParentNode is checked");
        for(Node n : list){
          n.check();
        }
    }
    public void add(Node node) {
        list.add(node);
    }
    public void remove(Node node) {
        list.remove(node);
    }
}

语言与模式-08适配器模式

意图

将一个类的接口转换成另外一个客户希望的接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

适用性

Java实现

假设目前做一个新系统,有如下代码结构。

public interface Car{
     public void drive();
}
public class Benz implements Car{
     public void drive(){
          System.out.println("Benz run");
     }
}
public class Cruze implements Car{
     public void drive(){
          System.out.println("Cruze run");
     }
}

有一个老系统,里面有如下代码

public class Smart{
     public void run(){
         System.out.println("Smart run");
     }
}

语言与模式-07代理模式

意图

为其他对象提供一种代理以控制对这个对象的访问。

适用性

在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。下面是一些可以使用Proxy模式常见情况:

Java实现

//工厂接口
public interface ItemFactory{
     public Item getItem();
}
//工厂实现,Item就不实现了,随便怎么写都行
public class ItemFactoryImpl implements ItemFactory{
      public Item getItem(){
          return new Item();
      }
}
//商店类,就是代理
public class Shop implements ItemFactory{
     private ItemFactory factory = new ItemFactoryImpl();
     public Item getItem(){
          System.out.println("附加服务");
          return factory.getItem();
     }
}
//实际调用
public class Main{
     public static void main(String[] args){
          ItemFactory f = new Shop();
          f.getItem();
     }
}

语言与模式-06门面模式

意图

为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

适用性

Java实现

public class Camara {
    public void turnOn(){
        System.out.println("开启摄像头!");
    }
    public void turnOff(){
        System.out.println("关闭摄像头!");
    }
}
public class Light {
    public void turnOn(){
        System.out.println("开灯!");
    }
    public void turnOff(){
        System.out.println("关灯!");
    }
}

语言与模式-05生成器模式

意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用性

Java实现

// 待构建产品
class Starbucks {
    private String size;
    private String drink;
    public void setSize(String size) {
        this.size = size;
    }
    public void setDrink(String drink) {
        this.drink = drink;
    }
}
//抽象builder
abstract class StarbucksBuilder {
    protected Starbucks starbucks;
    public Starbucks getStarbucks() {
        return starbucks;
    }
    public void createStarbucks() {
        starbucks = new Starbucks();
        System.out.println("a drink is created");
    }
    public abstract void buildSize();
    public abstract void buildDrink();
}

语言与模式-04原型模式

意图

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

适用性

Java实现

//浅拷贝
public class A implements Cloneable{
    private String str;
    private B b;
    public void setStr(String str){
        this.str = str;
    }
    public String getStr(){
        return str;
    }
    public B getB() {
        return b;
    }
    public void setB(B b) {
        this.b = b;
    }
    @Override
    protected Object clone(){
        A a = null;
        try {
            a = (A) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return a;
    }
    public static void main(String[] args) {
        A a = new A();
        a.setStr("Hello");
        B b = new B();
        b.setStr("Hello B");
        a.setB(b);
        System.out.println("a-str:" + a.getStr());
        System.out.println("a-b:" + a.getB().getStr());
        A ac = null;
        ac = (A) a.clone();
        System.out.println("ac-str:" + ac.getStr());
        System.out.println("ac-b:" + ac.getB().getStr());
        a.setStr("Hello A");
        b.setStr("Hello BB");
        a.setB(b);
        System.out.println("a-str:" + a.getStr());
        System.out.println("a-b:" + a.getB().getStr());
        System.out.println("ac-str:" + ac.getStr());
        System.out.println("ac-b:" + ac.getB().getStr());
    }
}