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

相关文章

来自专栏菩提树下的杨过

java:POI导出excel

POI是一个开源项目,专用于java平台上操作MS OFFICE,企业应用开发中可用它方便导出Excel. 下面是使用示例: 1、maven中先添加依赖项 1 ...

2525
来自专栏mySoul

设计模式 里氏替换原则

在场景中,三毛需要什么枪支,就直接new 出一个枪支即可,然后其内通过抽象类获取到对象,然后对齐进行修饰

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

一个例子理解C#位移

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

2007
来自专栏机器学习入门

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

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

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

codevs 1213 解的个数

1213 解的个数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 已知整数x...

3344
来自专栏HansBug's Lab

2751: [HAOI2012]容易题(easy)

2751: [HAOI2012]容易题(easy) Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1087 ...

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

《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...

1604
来自专栏進无尽的文章

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

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

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

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

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

941
来自专栏wannshan(javaer,RPC)

dubbo序列化过程源码分析

先看下dubbo在serialize层的类设计方案 序列化方案的入口,是接口Serialization的实现类。 /** * Serialization. ...

7339

扫码关注云+社区