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

相关文章

来自专栏我和未来有约会

简练的视图模型 ViewModel

patterns & practices Developer Center 发布了 Unity Application Block 1.2 for Silver...

2199
来自专栏Golang语言社区

Knapsack problem algorithms for my real-life carry-on knapsack

I'm a nomad and live out of one carry-on bag. This means that the total weight o...

1142
来自专栏余生开发

echarts太阳分布图-饼图来回穿梭

var dom = document.getElementById("container");

1202
来自专栏专知

2018年SCI期刊最新影响因子排行,最高244,人工智能TPAMI9.455

2018年6月26日,最新的SCI影响因子正式发布,涵盖1万2千篇期刊。CA-Cancer J Clin 依然拔得头筹,其影响因子今年再创新高,达244.585...

1292
来自专栏Hadoop数据仓库

Oracle sqlldr 如何导入一个日期列

1. LOAD DATA INFILE * INTO TABLE test FIELDS TERMINATED BY X'9' TRAILING NULLCO...

1816
来自专栏跟着阿笨一起玩NET

c# 使用timer定时器操作,上次定时到了以后,下次还未执行完怎么处理

------解决方案-------------------------------------------------------- 开始的时候,禁用定时器,你...

2701
来自专栏前端儿

Web 前端颜色值--字体--使用,整理整理

颜色值 CSS 颜色使用组合了红绿蓝颜色值 (RGB) 的十六进制 (hex) 表示法进行定义。对光源进行设置的最低值可以是 0(十六进制 00)。最高值是 2...

2372
来自专栏linux驱动个人学习

高通msm8909耳机调试

1、DTS相应修改: DTS相关代码:kernel/arch/arm/boot/dts/qcom/msm8909-qrd-skuc.dtsi: 1 s...

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

java.base.jmod

/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/jmods$ jmod list java....

1112
来自专栏Petrichor的专栏

Dataset 列表:机器学习研究

In computer vision, face images have been used extensively to develop face recog...

1541

扫码关注云+社区