设计模式之禅笔记3

来源:互联网 发布:世界征服者3 mac 编辑:程序博客网 时间:2024/06/07 05:47

适配器模式

定义:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作。
适配器模式又叫变压器模式,也叫做包装模式。
适配器模式的三个角色:
1. target:目标角色。定义把其他类转换为何种接口,也就是我们的期望接口。
2. Adaptee:原角色。你想把谁转换成目标角色,这个谁就是原角色。它是已经存在的、运行良好的类或对象。经过适配器角色的包装,它会成为一个崭新的角色。
3. Adapter:适配器角色。通过继承或类关联的方式,把原角色转换成目标角色。
通用源码:

public interface Target {    //目标角色有自己的方法    public void request();}public class ConcreteTarget implements Target {    public void request() {        System.out.println("I have nothing to do. if you need any help,pls call me!");  }}public class Adaptee{    //原有的业务逻辑    public void doSomething(){        System.out.println("I'm kind of busy,leave me alone,pls!");    }}public class Adapter extends Adaptee implements Target {    public void request() {        super.doSomething();    }}public class Client {    public static void main(String[] args) {        //原有的业务逻辑        Target target = new ConcreteTarget();        target.request();        //增加了适配器角色之后的业务逻辑        Target target2 = new Adapter();        target2.request();    }}
  • 优点:可以让两个没有任何关系的类在一起运行。增加了类的透明性。提高了类的服用度。灵活性非常好。如果某一天不想哟适配器了,删除掉这个适配器就可以了,其他的代码不用修改。
  • 使用场景:你有动机修改一个已经投产中的接口时,适配器模式可能是最适合你的选择。比如系统扩展了,需要使用一个已有或新建立的类,但这个类又不符合系统的接口,便可以使用适配器模式。
  • 注意事项:适配器模式不是为了解决还在开发阶段的问题,而是解决正在服役的项目问题。主要使用场景是扩展应用。而且项目一定要遵守依赖倒置原则和里氏替换原则,否则即使在适合使用适配器的场景下,也会带来非常大的改造。

适配器模式的扩展:
对象适配器。
与上面的类适配器的区别是:类适配器是类间继承,对象适配器是对象的合成关系。也可以说是类的关联关系。对象适配器是通过类间的关联关系进行耦合的,因此比较灵活,比如修补原角色的隐形缺陷,关联其他对象等。而类适配器只能通过复写原角色的方法进行扩展。实际项目中对象适配器用得比较多。

迭代器模式

定义:它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。
注:目前是一个没落的模式,基本没人会单独写一个迭代器,除非是产品性质的开发。
角色:
1. Iterator抽象迭代器:负责定义访问和遍历元素的接口。而且基本上是有固定的3个方法。first()获得第一个元素,next()访问下一个元素,isDone()是否已经访问到底部。
2. ConcreteIterator具体迭代器:实现迭代器接口,完成容器元素的遍历。
3. Aggregate抽象容器:提供创建具体迭代器角色的接口,必然提供一个类似createIterator这样的方法。
4. ConcreteAggregate具体容器:创建出容纳迭代器对象。
通用源码:

public interface Iterator{    public Object next();    public boolean hasNext();    public boolean remove();}public class ConcreteIterator implements Iterator{    private Vector vector = new Vector();    public int crusor = 0;    public ConcreteIterator(Vector _vector){        this.vector = _vector;    }    public boolean hasNext(){        if(this.crusor == this.vector.size()){            return false;        }else{            return true;        }    }    public Object next(){        Object result = null;        if(this.hasNext()){            result = this.vector.get(this.cursor++);        }else{            result = null;        }        return result;    }    public boolean remove(){        this.vector.remove(this.cursor);        return true;    }}public interface Aggregate(){    public void add(Object object);    public void remove(Object object);    public Iterator iterator();}public class ConcreteAggregate implements Aggregate{    private Vecotr vector = new Vector();    public void add(Object object){        this.vector.add(object);    }    public void remove(Object object){        this.vector.remove(object);    }    public Iterator iterator(){        return new ConcreteIterator(this.vector);    }}public class Client {    public static void main(String[] args) {        Aggregate agg = new ConcreteAggregate();        agg.add("abc");        agg.add("aaa");        agg.add("1234");        Iterator iterator = agg.iterator();        while(iterator.hasNext()){            System.out.println(iterator.next());        }    }}

java已经把迭代器写好了。因为有很多容器类。也不用我们再去写迭代器模式了。

组合模式

将对象组合成树形结构以表示“部分–整体”的层次结构,使得用户对单个和组合对象的使用具有一致性。
角色:
1. Component抽象构件角色:定义组合对象的共有方法和属性,可以定义一些 默认的行为或属性。
2. Leaf叶子构件:其下再也没有其他的分支。也就是遍历的最小单位。
3. Composite树枝构件:组合树枝节点和叶子节点形成一个树形结构。
通用源码:

public abstract class Component {    //个体和公体都具有的共享    public void doSomething(){    }}public class Composite extends Component {    //构件容器    private ArrayList<Component> componentArrayList = new ArrayList<Component>();    //增加一个叶子构件或树枝构件    public void add(Component component){        this.componentArrayList.add(component);    }    public void remove(Component component){        this.componentArrayList.remove(component);    }    //获得分支下所有的叶子构件和分支构件    public ArrayList<Component> getChildren(){        return this.componentArrayList;    }}public class Leaf extends Component {    /*     * //可以覆写父类方法     * public void doSomething(){     *      * }     */}public class Client {    public static void main(String[] args) {        Composite root = new Composite();        root.doSomething();        Composite branch = new Composite();        Leaf leaf = new Leaf();        root.add(branch);        branch.add(leaf);           }    public static void display(Composite root){        for(Component c:root.getChildren()){            if(c instanceof Leaf){                 c.doSomething();            }else{                 display((Composite)c);            }        }    }}

优点:
1. 高层模块调用简单。一棵树形结构的所有节点都是Component。局部和整体对调用者来说没有任何区别。高层模块不必关系自己处理的是单个对象还是整个组合结构。
2. 节点自由增加。想增加一个节点只要找到他的父节点就成。非常容易扩展。
缺点:在场景类中的定义中,使用树枝和树叶时直接用了实现类,与依赖倒置原则冲突。
使用场景:
1. 维护和展示部分–整体关系的场景,如树形菜单,文件和文件夹管理等。
2. 从一个整体能够独立出部分模块或功能的场景。

0 0