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 条评论
登录 后参与评论

相关文章

来自专栏進无尽的文章

编码篇 - 正则表达式及其相关

有时我们需要在一大段长文本中过滤出我们需要的字段,或者检验该文本是否符合要求(该文本是否是邮箱,链接,电话号码或身份证),这时候就需要用到正则表达式了,当然我们...

1182
来自专栏Porschev[钟慰]的专栏

一个例子理解C#位移

很多人提问,不知道C#位移,可能有些人在面试中也遇到过 其实很简单。。。 C#位移运算符: 左移:<< 右移:>> 位移理解可能简单一些:其实就是数据转换成二进...

2167
来自专栏一个会写诗的程序员的博客

《Kotlin极简教程》第五章 Kotlin面向对象编程(OOP)一个OOP版本的HelloWorld构造函数传参Data Class定义接口&实现之写pojo bean定一个Rectangle对象封

We frequently create a class to do nothing but hold data. In such a class some s...

2304
来自专栏小樱的经验随笔

Codeforces 842A Kirill And The Game【暴力,水】

A. Kirill And The Game time limit per test:2 seconds memory limit per test:256 m...

2907
来自专栏机器学习入门

挑战程序竞赛系列(86):3.6极限情况(3)

挑战程序竞赛系列(86):3.6极限情况(3) 传送门:AOJ 2201: Immortal Jewels 翻译参考至hankcs: http://www....

22310
来自专栏算法修养

HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)

Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja...

3107
来自专栏数据结构与算法

3027 线段覆盖 2

3027 线段覆盖 2  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果 题目描述 Descript...

2956
来自专栏wym

2013年多校赛 hdu4607

   那么就考虑树上最长距离,树的直径, 如果访问的点大于树的直径就要走回头路,答案即多的数乘2加上原来树的直径

1235
来自专栏数据结构与算法

洛谷P3763 [TJOI2017]DNA(后缀数组 RMQ)

具体来说,每次比较当前后缀和\(S_0\)的lcp,如果长度\(< N\)的话就从不合法的位置继续匹配

1171
来自专栏数据之美

Python Tips, Tricks, and Hacks

一、快速技巧 1.1、4 种引号 '  '''  "  """  print """I wish that I'd never heard him say...

2735

扫码关注云+社区

领取腾讯云代金券