设计模式之禅笔记3

适配器模式

定义:将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够一起工作。
适配器模式又叫变压器模式,也叫做包装模式。
适配器模式的三个角色:
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值