23种设计模式详解(四)

1.装饰模式(Decorator Pattern)

顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例。

举例:穿上漂亮的衣服美美的化个妆谁还不是小仙女咋地。

接口:

public interface beBeautiful {
    public void beautiful();
}

华服:

public class hotDresses implements beBeautiful {
    @Override
    public void beautiful() {
        System.out.println("穿上漂亮的衣服");
    }
}

美妆:

public class Cosmetic implements beBeautiful {
    private beBeautiful beautiful;

    public Cosmetic(beBeautiful beautiful) {
        this.beautiful = beautiful;
    }

    @Override
    public void beautiful() {
        System.out.println("画一个美美的妆");
        beautiful.beautiful();
        System.out.println("谁还不是小仙女咋地");

    }
}

秒变小仙女:

public class You {
    public static void main(String[] args){
        beBeautiful be=new hotDresses();
        beBeautiful tt=new Cosmetic(be);
        tt.beautiful();
    }
}

结果:

装饰器模式的应用场景:

1、需要扩展一个类的功能。

2、动态的为一个对象增加功能,而且还能动态撤销。(继承不能做到这一点,继承的功能是静态的,不能动态增删)

2.迭代器模式(Iterator Pattern)

迭代器模式就是顺序访问聚集中的对象,一般来说,集合中非常常见,如果对集合类比较熟悉的话,理解本模式会十分轻松。这句话包含两层意思:一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问。

举例:模拟一个集合类的过程。

迭代器接口:

public interface Iterator {
    //前遍历
    public Object previous();
    //后遍历
    public Object next();
    //判断是否有下一个
    public boolean hasNext();
    //取第一个元素
    public Object first();
}

集合接口:

public interface Collection {
    public Iterator iterator();
    //获取集合所有元素
    public Object get(int i);
    //获取集合大小
    public int size();
}

迭代器实现类:

public class myIterator implements Iterator {
    private Collection collection;
    private int num=-1;

    public myIterator(Collection collection) {
        this.collection = collection;
    }

    @Override
    public Object previous() {
        if(num>0){
            num--;
        }
        return collection.get(num);
    }

    @Override
    public Object next() {
        if(num<collection.size()-1){
            num++;
        }
        return collection.get(num);
    }

    @Override
    public boolean hasNext() {
        if(num<collection.size()-1){
            return true;
        }else{
            return false;
        }
    }

    @Override
    public Object first() {
        num=0;
        return collection.get(num);
    }
}

集合实现类:

public class myColllection implements Collection {
    public String string[]={"1","2","3","4","5"};
    @Override
    public Iterator iterator() {
        return new myIterator(this);
    }

    @Override
    public Object get(int i) {
        return string[i];
    }

    @Override
    public int size() {
        return string.length;
    }
}

测试:

public class Test {
    public static void main(String[] args){
        Collection c=new myColllection();
        Iterator i=c.iterator();
        while (i.hasNext()){
            System.out.println(i.next());
        }
    }
}

结果:

Java.util.Iterable接口只有一个方法就是iterator(),也就是说通过这个方法可以遍历聚集类中的所有方法和属性,基本上所有高级的语言都有Iterator这个接口或者实现,Java已经把迭代器给我们准备了,我们再去写迭代器就有点儿多此一举,所以迭代器模式我们基本不用自己去实现,直接使用List或者Map就可以完整的解决问题。但是我们也必须清楚他的实现过程,这样我们就可以写出自己的集合类,甚至框架!

3.组合模式(Composite Pattern)

组合模式有时又叫部分-整体模式在处理类似树形结构的问题时比较方便。

public class TreeNode{
    private String name;
    private TreeNode parent;
    private Vector<TreeNode> children=new Vector<TreeNode>();
    public TreeNode(String name){
        this.name=name;
    }

    public TreeNode getParent() {
        return parent;
    }

    public void setParent(TreeNode parent) {
        this.parent = parent;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //添加孩子节点  
    public void add(TreeNode node){
        children.add(node);
    }
    //删除孩子节点
    public void remove(TreeNode node){
        children.remove(node);
    }
    //取得孩子节点
    public Enumeration<TreeNode> etChildren(){
        return children.elements();
    }
}

实现:

public class Tree {
    TreeNode root=null;

    public Tree(String name) {
        root = new TreeNode(name);
    }
    public static void main(String[] args){
        Tree tree=new Tree("A");
        TreeNode nodeB=new TreeNode("B");
        TreeNode nodeC=new TreeNode("C");
        TreeNode nodeD=new TreeNode("D");
        TreeNode nodeE=new TreeNode("E");
        TreeNode nodeF=new TreeNode("#");
        TreeNode nodeG=new TreeNode("#");
        TreeNode nodeH=new TreeNode("#");
        TreeNode nodeI=new TreeNode("#");
        TreeNode nodeJ=new TreeNode("#");
        TreeNode nodeK=new TreeNode("#");
        nodeD.add(nodeF);
        nodeD.add(nodeG);
        nodeE.add(nodeH);
        nodeE.add(nodeI);
        nodeB.add(nodeD);
        nodeB.add(nodeJ);
        nodeC.add(nodeE);
        nodeC.add(nodeK);
        tree.root.add(nodeB);
        tree.root.add(nodeC);

    }
}

使用场景:将多个对象组合在一起进行操作,常用于表示树形结构中,例如二叉树等。

4.观察者模式(Observer Pattern)

当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。

观察者接口:

public interface Observer {
    public void update();
}

第一个观察者:

public class myObserver1 implements Observer{
    @Override
    public void update() {
        System.out.println("myObserver1 has changed");
    }
}

第二个观察者:

public class myObserver2 implements Observer {
    @Override
    public void update() {
        System.out.println("myObserver2 has changed");
    }
}

对象接口:

public interface Subject {
    //增加观察者
    public void add(Observer observer);
    //删除观察者
    public void delete(Observer observer);
    //通知所有观察者
    public void notifyObservers();
    //自己的方法
    public void operation();
}

需要监控的对象列表:

public abstract class AbstractSubject implements Subject {
    private Vector<Observer> vector = new Vector<Observer>();
    @Override
    public void add(Observer observer) {
        vector.add(observer);
    }

    @Override
    public void delete(Observer observer) {
        vector.remove(observer);
    }

    @Override
    public void notifyObservers() {
        Enumeration<Observer> enumo = vector.elements();
        while(enumo.hasMoreElements()){
            enumo.nextElement().update();
        }

    }

}

主对象:

public class mySubject extends AbstractSubject {
    @Override
    public void operation() {
        System.out.println("update self");
        notifyObservers();
    }
}

测试:

public class Test {
    public static void main(String[] args){
        Subject su=new mySubject();
        su.add(new myObserver1());
        su.add(new myObserver2());
        su.operation();
    }
}

结果:

源码:

链接: https://pan.baidu.com/s/15nzQHIsCLJmdIUBdDQzd5Q

密码: 4qjs

原文发布于微信公众号 - Java大联盟(javaunion)

原文发表时间:2018-05-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小勇DW3

Spring中使用RedisTemplate操作Redis(spring-data-redis)

Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zs...

1483
来自专栏趣学算法

数据结构 第15讲 一场说走就走的旅行——最短路径

本内容来源于《趣学算法》,在线章节:http://www.epubit.com.cn/book/details/4825

1161
来自专栏闵开慧

java概念2

1 文件操作 public class FileTest { public static void main(String[] args) throw...

3228
来自专栏郭耀华‘s Blog

剑指offer第二天

18.二叉树的镜像 操作给定的二叉树,将其变换为源二叉树的镜像。 ? /** public class TreeNode { int val = 0...

2586
来自专栏Ryan Miao

Java8-理解Collector

2734
来自专栏和蔼的张星的图像处理专栏

数据结构栈队列链表树二叉查找树

这学期刚回到所里的时候把c++数据结构看了一遍,基本的数据结构照着视频也敲了一遍,不过那个时候自己对c++的了解只限于一些基本的语法,c++primer也还没有...

1224
来自专栏大闲人柴毛毛

Java8新特性——StreamAPI(二)

1. 收集器简介 收集器用来将经过筛选、映射的流进行最后的整理,可以使得最后的结果以不同的形式展现。 collect方法即为收集器,它接收Collector接...

2775
来自专栏恰同学骚年

C# 中的委托和事件

文中代码在VS2005下通过,由于VS2003(.Net Framework 1.1)不支持隐式的委托变量,所以如果在一个接受委托类型的位置直接赋予方法名,...

742
来自专栏偏前端工程师的驿站

基础野:细说有符号整数

Breif                                本来只打算理解JS中0.1 + 0.2 == 0.30000000000000004的...

19310
来自专栏算法修养

2016天梯模拟赛 进阶题解

L2-005 集合相似度 题目链接: https://www.patest.cn/contests/gplt/L2-005 题目的意思是要求两个集合的交集中...

4059

扫码关注云+社区