Windows Embedded Compact 7开发条件之搭建

设计模式(Design Patterns)

 

**一、设计模式的分类
**

圆来说设计模式分为三要命接近:

创建型模式,共五种植:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种植:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一栽:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

实际上还有少类:并发型模式与线程池模式。用一个图片来完全描述一下:

图片 1

 

 

亚、设计模式的六异常口径

1、开闭原则(Open Close Principle)

开闭原则就是针对扩大开放,对修改关闭。在次要开展拓展之时节,不可知去修改原有的代码,实现一个热插拔的机能。所以一律句子话概括就是是:为了要程序的扩展性好,易于维护和升级换代。想如果达标这样的作用,我们要用接口及抽象类,后面的求实统筹中我们见面涉嫌这点。

2、里氏代表换原则(Liskov Substitution Principle)

里氏代表换原则(Liskov Substitution Principle
LSP)面向对象设计之核心原则之一。
里氏代表换原则被说,任何基类可以起的地方,子类一定好出现。
LSP是延续复用的木本,只有当衍生类可以替换掉基类,软件单位的功用不遭震慑时,基类才能当真为复用,而衍生类也会当基类的基本功及搭新的一言一行。里氏代表换原则是针对“开-闭”原则的续。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的接轨关系就是是抽象化的现实性实现,所以里氏代换原则是针对性实现抽象化的具体步骤的正规。——
From Baidu 百科

3、依赖反原则(Dependence Inversion Principle)

此是开闭原则的根基,具体内容:真对接口编程,依赖让肤浅而非因让现实。

4、接口隔离原则(Interface Segregation Principle)

本条标准的意是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们见到,其实设计模式就是是一个软件的计划性思想,从大型软件架构出发,为了提升与保安好。所以上文中数面世:降低因,降低耦合。

5、迪米特法则(最少知道原则)(Demeter Principle)

为何让最少知道原则,就是说:一个实体应当尽量少的及其它实体之间时有发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)

原则是竭尽使合成/聚合的道,而不是行使持续。

 

 

其三、Java的23着设计模式

起当下同样块开始,我们详细介绍Java中23栽设计模式的概念,应用场景相当景象,并结合他们的表征与设计模式的标准化开展辨析。

1、工厂方法模式(Factory Method)

厂子方法模式分为三栽:

11、普通工厂模式,就是建一个厂子类,对促成了扳平接口的组成部分近似进行实例的创办。首先看下干图:

图片 2

 

举例如下:(我们选一个发送邮件和短信的例子)

首先,创建二者的一块接口:

public interface Sender {  
    public void Send();  
}  

下,创建实现类似:

图片 3图片 4

public class MailSender implements Sender {  
    @Override  
    public void Send() {  
        System.out.println("this is mailsender!");  
    }  
}  

View Code

图片 5图片 6

1 public class SmsSender implements Sender {  
2   
3     @Override  
4     public void Send() {  
5         System.out.println("this is sms sender!");  
6     }  
7 }  

View Code

末段,建工厂类:

图片 7图片 8

 1 public class SendFactory {  
 2   
 3     public Sender produce(String type) {  
 4         if ("mail".equals(type)) {  
 5             return new MailSender();  
 6         } else if ("sms".equals(type)) {  
 7             return new SmsSender();  
 8         } else {  
 9             System.out.println("请输入正确的类型!");  
10             return null;  
11         }  
12     }  
13 }  

View Code

咱来测试下:

图片 9图片 10

public class FactoryTest {  

    public static void main(String[] args) {  
        SendFactory factory = new SendFactory();  
        Sender sender = factory.produce("sms");  
        sender.Send();  
    }  
}  

View Code

输出:this is sms sender!

22、多只厂子方法模式,是指向常见工厂方法模式的改进,在一般工厂方法模式被,如果传递的字符串出错,则未能够科学创建对象,而多只厂子方法模式是提供多单工厂方法,分别创建对象。关系图:

图片 11

拿地方的代码做生修改,改动下SendFactory类就推行,如下:

图片 12图片 13

public Sender produceMail(){  
        return new MailSender();  
    }  

    public Sender produceSms(){  
        return new SmsSender();  
    }  
}  

View Code

测试类如下:

图片 14图片 15

public class FactoryTest {  

    public static void main(String[] args) {  
        SendFactory factory = new SendFactory();  
        Sender sender = factory.produceMail();  
        sender.Send();  
    }  
}  

View Code

输出:this is mailsender!

33、静态工厂方法模式,将地方的多个厂子方法模式里的点子置为静态的,不需创造实例,直接调用即可。

图片 16图片 17

public class SendFactory {  

    public static Sender produceMail(){  
        return new MailSender();  
    }  

    public static Sender produceSms(){  
        return new SmsSender();  
    }  
}  

View Code

图片 18图片 19

public class FactoryTest {  

    public static void main(String[] args) {      
        Sender sender = SendFactory.produceMail();  
        sender.Send();  
    }  
}  

View Code

输出:this is mailsender!

圆来说,工厂模式可:凡是出现了大量之产品要创造,并且拥有协同的接口时,可以经过工厂方法模式进行创办。在上述之老三种模式中,第一种使传入的字符串有误,不能够正确创建对象,第三种植相对于次种,不需实例化工厂类,所以,大多数状下,我们会选用第三种植——静态工厂方法模式。

2、抽象工厂模式(Abstract Factory)

工厂方法模式产生一个问题就,类的创始依赖工厂类,也就是说,如果想要开展程序,必须对工厂类进行改动,这违背了闭包原则,所以,从统筹角度考虑,有必然之题目,如何化解?就因此到虚幻工厂模式,创建多只厂子类,这样要用多新的力量,直接长新的厂类就可了,不需要修改前的代码。因为虚无工厂不太好掌握,我们先看图,然后就和代码,就比较易于懂。

图片 20

 

 请看例子:

图片 21图片 22

public interface Sender {  
    public void Send();  
}  

View Code

区区单实现类似:

图片 23图片 24

public class MailSender implements Sender {  
    @Override  
    public void Send() {  
        System.out.println("this is mailsender!");  
    }  
}  

View Code

图片 25图片 26

public class SmsSender implements Sender {  

    @Override  
    public void Send() {  
        System.out.println("this is sms sender!");  
    }  
}  

View Code

星星只厂子类:

图片 27图片 28

public class SendMailFactory implements Provider {  

    @Override  
    public Sender produce(){  
        return new MailSender();  
    }  
} 

View Code

图片 29图片 30

public class SendSmsFactory implements Provider{  

    @Override  
    public Sender produce() {  
        return new SmsSender();  
    }  
}  

View Code

每当提供一个接口:

图片 31图片 32

public interface Provider {  
    public Sender produce();  
}  

View Code

测试类:

图片 33图片 34

public class Test {  

    public static void main(String[] args) {  
        Provider provider = new SendMailFactory();  
        Sender sender = provider.produce();  
        sender.Send();  
    }  
}  

View Code

实则这模式之利就,如果你现在纪念多一个效能:发就信息,则只有待开一个实现类似,实现Sender接口,同时召开一个厂类,实现Provider接口,就OK了,无需去改变现成的代码。这样做,拓展性较好!

3、单例模式(Singleton

单例对象(Singleton)是一律栽常用之设计模式。在Java应用被,单例对象能够确保在一个JVM中,该目标只是发生一个实例存在。这样的模式产生几个便宜:

1、某些类创建于累,对于一些重型的对象,这是均等笔大十分的系统开发。

2、省去了new操作符,降低了系内存的采用效率,减轻GC压力。

3、有些看似设交易所的基本交易引擎,控制在市流程,如果此类可以创造多只的话,系统完全乱了。(比如一个大军出现了差不多个司令员同时指挥,肯定会乱成一团),所以只有以单例模式,才能够担保核心交易服务器独立操纵总体工艺流程。

首先我们描绘一个简约的单例类:

图片 35图片 36

public class Singleton {  

    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
    private static Singleton instance = null;  

    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  

    /* 静态工程方法,创建实例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  

    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return instance;  
    }  
}  

View Code

这个近乎可以满足基本要求,但是,像这么毫无线程安全保安之切近,如果我们管其放入多线程的条件下,肯定就会见并发问题了,如何缓解?我们率先会想到对getInstance方法加synchronized关键字,如下:

图片 37图片 38

public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  

View Code

而是,synchronized关键字锁住的凡此目标,这样的用法,在性质达到会见具备下跌,因为每次调用getInstance(),都要指向目标及锁,事实上,只有在首先软创建对象的时节要加锁,之后虽未需要了,所以,这个地方需要改进。我们改变化下面这个:

图片 39图片 40

public static Singleton getInstance() {  
        if (instance == null) {  
            synchronized (instance) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
        return instance;  
    }

View Code

似乎缓解了前面涉嫌的问题,将synchronized关键字加于了里面,也就是说当调用的时刻是休待加锁之,只有当instance为null,并创建对象的当儿才需要加锁,性能有一定之晋升。但是,这样的状况,还是产生或发问题之,看下面的景况:在Java指令中开创目标以及赋值操作是分离进行的,也就是说instance
= new
Singleton();语句是分开点儿步执行之。但是JVM并无保证及时有限单操作的先后顺序,也就是说有或JVM会为新的Singleton实例分配空间,然后径直赋值给instance成员,然后又失去初始化这个Singleton实例。这样即使可能有错了,我们以A、B两只线程为条例:

a>A、B线程同时跻身了第一单if判断

b>A首先登synchronized块,由于instance为null,所以其执行instance =
new Singleton();

c>由于JVM内部的优化机制,JVM先画起了部分分配给Singleton实例的空域内存,并赋值给instance成员(注意这JVM没有从头初始化这个实例),然后A离开了synchronized块。

d>B进入synchronized块,由于instance此时不是null,因此她就去了synchronized块并拿结果返回给调用该方式的程序。

e>此时B线程打算以Singleton实例,却发现她从不于初始化,于是错误产生了。

因而程序还是生或来错误,其实程序在运行过程是格外复杂的,从马上点我们就可以看出,尤其是于描绘多线程环境下之主次还产生难度,有挑战性。我们针对拖欠次召开进一步优化:

图片 41图片 42

private static class SingletonFactory{           
        private static Singleton instance = new Singleton();           
    }           
    public static Singleton getInstance(){           
        return SingletonFactory.instance;           
    }  

View Code

实际上情况是,单例模式采用中类来维护单例的贯彻,JVM内部的机制能管当一个近似让加载的时,这个仿佛的加载过程是线程互斥的。这样当我们先是涂鸦调整用getInstance的时候,JVM能够帮助咱管instance只给创造同次于,并且会确保将赋值给instance的内存初始化完毕,这样我们即便毫无担心方的题材。同时该办法呢无非见面当率先浅调用的上用互斥机制,这样尽管解决了低性能问题。这样咱们临时总结一个周的单例模式:

图片 43图片 44

public class Singleton {  

    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  

    /* 此处使用一个内部类来维护单例 */  
    private static class SingletonFactory {  
        private static Singleton instance = new Singleton();  
    }  

    /* 获取实例 */  
    public static Singleton getInstance() {  
        return SingletonFactory.instance;  
    }  

    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return getInstance();  
    }  
}  

View Code

实际说它们到,也不肯定,如果以构造函数中丢掉来深,实例将永远得不顶创建,也会见拧。所以说,十分宏观的事物是没的,我们只能依据实际情形,选择最为契合自己运场景的落实方式。也有人这样实现:因为我们特需要在开立类的时光进行协同,所以如果拿创设与getInstance()分开,单独为创建加synchronized关键字,也是好的:

图片 45图片 46

public class SingletonTest {  

    private static SingletonTest instance = null;  

    private SingletonTest() {  
    }  

    private static synchronized void syncInit() {  
        if (instance == null) {  
            instance = new SingletonTest();  
        }  
    }  

    public static SingletonTest getInstance() {  
        if (instance == null) {  
            syncInit();  
        }  
        return instance;  
    }  
}  

View Code

考虑性能的话,整个程序只需要创建同不好实例,所以性能也不见面来什么影响。

补偿:采用”影子实例”的方式吧单例对象的属性同步创新

图片 47图片 48

public class SingletonTest {  

    private static SingletonTest instance = null;  
    private Vector properties = null;  

    public Vector getProperties() {  
        return properties;  
    }  

    private SingletonTest() {  
    }  

    private static synchronized void syncInit() {  
        if (instance == null) {  
            instance = new SingletonTest();  
        }  
    }  

    public static SingletonTest getInstance() {  
        if (instance == null) {  
            syncInit();  
        }  
        return instance;  
    }  

    public void updateProperties() {  
        SingletonTest shadow = new SingletonTest();  
        properties = shadow.getProperties();  
    }  
}  

View Code

经过单例模式的求学报告我们:

1、单例模式了解起来大概,但是现实贯彻起来还是来肯定的难度。

2、synchronized关键字锁定的是目标,在用的当儿,一定要是于适当的地方用(注意用采用锁的靶子同经过,可能有上并无是整个对象及成套过程都亟待锁)。

至这时候,单例模式基本已经谈了了,结尾处,笔者突然想到另一个题材,就是使类似的静态方法,实现单例模式之法力,也是立竿见影的,此处二者有什么两样?

先是,静态类非能够实现接口。(从类的角度说是可以的,但是那样就坏了静态了。因为接口中莫允生static修饰的方式,所以即使实现了吗是非静态的)

附带,单例可以为推初始化,静态类一般在首先潮加载是初始化。之所以延迟加载,是盖有点类似比较大,所以延迟加载有助于提升性。

还,单例类可以让延续,他的道可以为覆写。但是静态类内部方法都是static,无法给覆写。

末段一点,单例类比较灵敏,毕竟从贯彻上仅是一个普普通通的Java类,只要满足单例的中心需要,你可以当其中随心所欲的落实有别样力量,但是静态类不行。从上面这些包括中,基本得以见见两岸的别,但是,从另一方面说,我们地方最后实现之怪单例模式,内部就用一个静态类来落实之,所以,二者有很充分的关系,只是我们考虑问题之框框不同而已。两种思想的成,才会塑造出全面的解决方案,就比如HashMap采用数组+链表来促成平等,其实在受到有的是业务还是这么,单用不同的方来拍卖问题,总是有可取也产生弱点,最全面的道是,结合各个艺术的长处,才会顶好的缓解问题!

4、建造者模式(Builder)

工厂类模式供的是开创单个类的模式,而建造者模式则是以各种成品集中起来进行管制,用来创造复合对象,所谓复合对象就是凭有类有不同的性质,其实建造者模式就是是前面抽象工厂模式及最后的Test结合起来得到的。我们看一下代码:

尚同前面一样,一个Sender接口,两独实现类MailSender和SmsSender。最后,建造者类如下:

图片 49图片 50

public class Builder {  

    private List<Sender> list = new ArrayList<Sender>();  

    public void produceMailSender(int count){  
        for(int i=0; i<count; i++){  
            list.add(new MailSender());  
        }  
    }  

    public void produceSmsSender(int count){  
        for(int i=0; i<count; i++){  
            list.add(new SmsSender());  
        }  
    }  
}  

View Code

测试类:

图片 51图片 52

public class Test {  

    public static void main(String[] args) {  
        Builder builder = new Builder();  
        builder.produceMailSender(10);  
    }  
}  

View Code

起即点看有,建造者模式将过多效并到一个类里,这个近乎可创造出比较复杂的物。所以跟工程模式的分别就是是:工厂模式关注之是开创单个产品,而建造者模式则关注创造符合对象,多只片。因此,是挑工厂模式或建造者模式,依实际情形如果一定。

5、原型模式(Prototype)

原型模式则是创建型的模式,但是与工程模式没有关系,从名字即可见到,该模式之思维就是以一个目标作为原型,对那进展复制、克隆,产生一个及原对象类似的新目标。本小结会通过对象的复制,进行讲解。在Java中,复制对象是由此clone()实现之,先创造一个原型类:

图片 53图片 54

public class Prototype implements Cloneable {  

    public Object clone() throws CloneNotSupportedException {  
        Prototype proto = (Prototype) super.clone();  
        return proto;  
    }  
}  

View Code

充分简短,一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可转移成为自由的名称,因为Cloneable接口是个缺损接口,你得肆意定义实现类似的法门名,如cloneA或者cloneB,因为这边的要害是super.clone()这词话,super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的,具体怎么落实,我会以其它一样首文章被,关于解读Java中本地方法的调用,此处不再追究。在此刻,我以整合目标的浅复制和深复制来说一下,首先需要了解对象特别、浅复制的概念:

浅复制:将一个对象复制后,基本数据类的变量都见面再次创设,而引用类型,指向的还是本来对象所针对的。

深复制:将一个对象复制后,不论是基本数据类还有引用类型,都是又创设的。简单的话,就是深复制进行了完全彻底的复制,而浅复制不到底。

此间,写一个浓度复制的事例:

图片 55图片 56

public class Prototype implements Cloneable, Serializable {  

    private static final long serialVersionUID = 1L;  
    private String string;  

    private SerializableObject obj;  

    /* 浅复制 */  
    public Object clone() throws CloneNotSupportedException {  
        Prototype proto = (Prototype) super.clone();  
        return proto;  
    }  

    /* 深复制 */  
    public Object deepClone() throws IOException, ClassNotFoundException {  

        /* 写入当前对象的二进制流 */  
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(bos);  
        oos.writeObject(this);  

        /* 读出二进制流产生的新对象 */  
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
        ObjectInputStream ois = new ObjectInputStream(bis);  
        return ois.readObject();  
    }  

    public String getString() {  
        return string;  
    }  

    public void setString(String string) {  
        this.string = string;  
    }  

    public SerializableObject getObj() {  
        return obj;  
    }  

    public void setObj(SerializableObject obj) {  
        this.obj = obj;  
    }  

}  

class SerializableObject implements Serializable {  
    private static final long serialVersionUID = 1L;  
}  

View Code

只要贯彻深复制,需要使用流动的款式读入当前目标的次上前制输入,再写来二进制数据对应的对象。

俺们随后讨论设计模式,上篇文章我称得了了5种创建型模式,这回开,我以出口下7种植结构型模式:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。其中目标的适配器模式是各种模式的来源,我们看下面的觊觎:

图片 57

 适配器模式将某类的接口转换成客户端期望的外一个接口表示,目的是割除由于接口不兼容所招的接近的兼容性问题。主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。首先,我们来看看接近的适配器模式,先押类图:

图片 58

 

核心思想就是:有一个Source类,拥有一个方,待适配,目标接口时Targetable,通过Adapter类,将Source的功力扩展及Targetable里,看代码:

图片 59图片 60

public class Source {  

    public void method1() {  
        System.out.println("this is original method!");  
    }  
} 

View Code

图片 61图片 62

public interface Targetable {  

    /* 与原类中的方法相同 */  
    public void method1();  

    /* 新类的方法 */  
    public void method2();  
}  

View Code

图片 63图片 64

public class Adapter extends Source implements Targetable {  

    @Override  
    public void method2() {  
        System.out.println("this is the targetable method!");  
    }  
}  

View Code

Adapter类继承Source类,实现Targetable接口,下面是测试类:

图片 65图片 66

public class AdapterTest {  

    public static void main(String[] args) {  
        Targetable target = new Adapter();  
        target.method1();  
        target.method2();  
    }  
}  

View Code

输出:

this is original method!
this is the targetable method!

如此Targetable接口的兑现类似就有了Source类的效应。

目标的适配器模式

基本思路和类的适配器模式相同,只是用Adapter类作改,这次未连续Source类,而是所有Source类的实例,以高达缓解兼容性的题材。看图:

图片 67

 

独自需要修改Adapter类的源码即可:

图片 68图片 69

public class Wrapper implements Targetable {  

    private Source source;  

    public Wrapper(Source source){  
        super();  
        this.source = source;  
    }  
    @Override  
    public void method2() {  
        System.out.println("this is the targetable method!");  
    }  

    @Override  
    public void method1() {  
        source.method1();  
    }  
}  

View Code

测试类:

图片 70图片 71

public class AdapterTest {  

    public static void main(String[] args) {  
        Source source = new Source();  
        Targetable target = new Wrapper(source);  
        target.method1();  
        target.method2();  
    }  
}  

View Code

输出和第一种植同等,只是适配的法子不同而已。

老三栽适配器模式是接口的适配器模式,接口的适配器是这般的:有时我们描绘的一个接口中发出差不多只抽象方法,当我们刻画该接口的落实类似时,必须兑现该接口的装有术,这显然有时比较浪费,因为并无是颇具的法子还是咱们得之,有时只是需要某个部分,此处为解决这题目,我们引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了拖欠接口,实现了所有的方,而我辈无跟原来之接口打交道,只及欠抽象类取得联系,所以我们形容一个类似,继承该抽象类,重写我们需要之艺术就实施。看一下类图:

图片 72

斯可怜好明,在实际支出被,我们啊不时会碰到这种接口中定义了最好多之点子,以致吃有时我们在局部兑现类似中并无是还需要。看代码:

图片 73图片 74

public interface Sourceable {  

    public void method1();  
    public void method2();  
}  

View Code

抽象类Wrapper2:

图片 75图片 76

public abstract class Wrapper2 implements Sourceable{  

    public void method1(){}  
    public void method2(){}  
}  

View Code

图片 77图片 78

public class SourceSub1 extends Wrapper2 {  
    public void method1(){  
        System.out.println("the sourceable interface's first Sub1!");  
    }  
}  

View Code

图片 79图片 80

public class SourceSub2 extends Wrapper2 {  
    public void method2(){  
        System.out.println("the sourceable interface's second Sub2!");  
    }  
}  

View Code

图片 81图片 82

public class WrapperTest {  

    public static void main(String[] args) {  
        Sourceable source1 = new SourceSub1();  
        Sourceable source2 = new SourceSub2();  

        source1.method1();  
        source1.method2();  
        source2.method1();  
        source2.method2();  
    }  
}  

View Code

测试输出:

the sourceable interface’s first Sub1!
the sourceable interface’s second Sub2!

达成了俺们的功力!

 讲了这么多,总结一下叔种适配器模式的动场景:

恍如的适配器模式:当期用一个类改换成为饱其他一个新接口的切近时,可以用类的适配器模式,创建一个新类,继承原有的接近,实现新的接口即可。

靶的适配器模式:当期以一个对象转换成饱另一个初接口的靶子时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的不二法门被,调用实例的方式就行。

接口的适配器模式:当不希望实现一个接口中所有的点子时,可以创建一个架空类Wrapper,实现所有术,我们写别的好像的时,继承抽象类即可。

7、装饰模式(Decorator)

顾名思义,装饰模式就是是受一个目标多有初的功效,而且是动态的,要求装饰对象与让点缀对象实现同一个接口,装饰对象具备被装饰对象的实例,关系图如下:

图片 83

Source类是吃装饰类,Decorator类是一个装饰类,可以吧Source类动态的增长一些效能,代码如下:

图片 84图片 85

public interface Sourceable {  
    public void method();  
} 

View Code

图片 86图片 87

public class Source implements Sourceable {  

    @Override  
    public void method() {  
        System.out.println("the original method!");  
    }  
}  

View Code

图片 88图片 89

public class Decorator implements Sourceable {  

    private Sourceable source;  

    public Decorator(Sourceable source){  
        super();  
        this.source = source;  
    }  
    @Override  
    public void method() {  
        System.out.println("before decorator!");  
        source.method();  
        System.out.println("after decorator!");  
    }  
}  

View Code

测试类:

图片 90图片 91

public class DecoratorTest {  

    public static void main(String[] args) {  
        Sourceable source = new Source();  
        Sourceable obj = new Decorator(source);  
        obj.method();  
    }  
} 

View Code

输出:

before decorator!
the original method!
after decorator!

装饰器模式之运场景:

1、需要扩大一个类似的机能。

2、动态的为一个对象多效果,而且还能动态撤销。(继承不克形成及时一点,继承的职能是静态的,不能够动态增删。)

症结:产生了多般之靶子,不易排错!

8、代理模式(Proxy)

实在每个模式名称即使标明了拖欠模式之意,代理模式就是是基本上一个代理类出来,替原对象开展有操作,比如我们当租房子的时节回来寻找中介,为什么也?因为你针对该地方房屋的音讯控的不够健全,希望物色一个又熟识的人失去帮你开,此处的代理就是这个意思。再设我们片时候打官司,我们得请律师,因为律师在法律方面有特长,可以给我们开展操作,表达我们的想法。先来探关系图:图片 92

 

根据上文的阐述,代理模式就是比较易于的晓了,我们看下代码:

图片 93图片 94

public interface Sourceable {  
    public void method();  
}  

View Code

图片 95图片 96

public class Source implements Sourceable {  

    @Override  
    public void method() {  
        System.out.println("the original method!");  
    }  
}  

View Code

图片 97图片 98

public class Proxy implements Sourceable {  

    private Source source;  
    public Proxy(){  
        super();  
        this.source = new Source();  
    }  
    @Override  
    public void method() {  
        before();  
        source.method();  
        atfer();  
    }  
    private void atfer() {  
        System.out.println("after proxy!");  
    }  
    private void before() {  
        System.out.println("before proxy!");  
    }  
}  

View Code

测试类:

图片 99图片 100

public class ProxyTest {  

    public static void main(String[] args) {  
        Sourceable source = new Proxy();  
        source.method();  
    }  

}  

View Code

输出:

before proxy!
the original method!
after proxy!

代理模式的施用场景:

假如都部分艺术在动用的时候要对原有的法子进行改良,此时发出星星点点栽办法:

1、修改原有的法门来适应。这样违反了“对扩大开放,对修改关闭”的尺码。

2、就是运一个代理类调用原有的方式,且对产生的结果开展支配。这种办法就是是代理模式。

以代理模式,可以以作用划分的越来越清楚,有助于后期维护!

9、外观模式(Facade)

外观模式是为化解类似以及类似的拙的乘关系的,像spring一样,可以用接近与类中的干安排到布置文件中,而外观模式就是是以他们的涉及在一个Facade类中,降低了类类之间的耦合度,该模式被无干到接口,看下类图:(我们盖一个电脑的开行过程也例)

图片 101

咱先看下促成类似:

图片 102图片 103

public class CPU {  

    public void startup(){  
        System.out.println("cpu startup!");  
    }  

    public void shutdown(){  
        System.out.println("cpu shutdown!");  
    }  
}  

View Code

图片 104图片 105

public class Memory {  

    public void startup(){  
        System.out.println("memory startup!");  
    }  

    public void shutdown(){  
        System.out.println("memory shutdown!");  
    }  
} 

View Code

图片 106图片 107

public class Disk {  

    public void startup(){  
        System.out.println("disk startup!");  
    }  

    public void shutdown(){  
        System.out.println("disk shutdown!");  
    }  
}  

View Code

图片 108图片 109

public class Computer {  
    private CPU cpu;  
    private Memory memory;  
    private Disk disk;  

    public Computer(){  
        cpu = new CPU();  
        memory = new Memory();  
        disk = new Disk();  
    }  

    public void startup(){  
        System.out.println("start the computer!");  
        cpu.startup();  
        memory.startup();  
        disk.startup();  
        System.out.println("start computer finished!");  
    }  

    public void shutdown(){  
        System.out.println("begin to close the computer!");  
        cpu.shutdown();  
        memory.shutdown();  
        disk.shutdown();  
        System.out.println("computer closed!");  
    }  
}  

View Code

User类如下:

图片 110图片 111

public class User {  

    public static void main(String[] args) {  
        Computer computer = new Computer();  
        computer.startup();  
        computer.shutdown();  
    }  
}  

View Code

输出:

start the computer!
cpu startup!
memory startup!
disk startup!
start computer finished!
begin to close the computer!
cpu shutdown!
memory shutdown!
disk shutdown!
computer closed!

使我们从没Computer类,那么,CPU、Memory、Disk他们中以见面相互有实例,产生关系,这样见面造成深重的凭,修改一个像样,可能会见带动任何类似的改动,这不是咱们纪念要看到底,有了Computer类,他们中的关联让放在了Computer类里,这样尽管从至了解耦的意图,这,就是外观模式!

10、桥接模式(Bridge)

桥接模式就是是将东西与那个现实贯彻分开,使他们得以分级独立的变动。桥接的作用是:以抽象化与贯彻化解耦,使得两岸可以独立变化,像咱经常因此之JDBC桥DriverManager一样,JDBC进行连接数据库的时光,在相继数据库中进行切换,基本不需动太多之代码,甚至丝毫免用动,原因就是JDBC提供统一接口,每个数据库提供个别的实现,用一个名为数据库让之次序来桥接就实行了。我们来看望关系图:

图片 112

心想事成代码:

先期定义接口:

图片 113图片 114

public interface Sourceable {  
    public void method();  
}  

View Code

分别定义两独实现类似:

图片 115图片 116

public class SourceSub1 implements Sourceable {  

    @Override  
    public void method() {  
        System.out.println("this is the first sub!");  
    }  
}  

View Code

图片 117图片 118

public class SourceSub2 implements Sourceable {  

    @Override  
    public void method() {  
        System.out.println("this is the second sub!");  
    }  
}  

View Code

概念一个大桥,持有Sourceable的一个实例:

 

图片 119图片 120

public abstract class Bridge {  
    private Sourceable source;  

    public void method(){  
        source.method();  
    }  

    public Sourceable getSource() {  
        return source;  
    }  

    public void setSource(Sourceable source) {  
        this.source = source;  
    }  
}  

View Code

图片 121图片 122

public class MyBridge extends Bridge {  
    public void method(){  
        getSource().method();  
    }  
} 

View Code

测试类:

 

图片 123图片 124

public class BridgeTest {  

    public static void main(String[] args) {  

        Bridge bridge = new MyBridge();  

        /*调用第一个对象*/  
        Sourceable source1 = new SourceSub1();  
        bridge.setSource(source1);  
        bridge.method();  

        /*调用第二个对象*/  
        Sourceable source2 = new SourceSub2();  
        bridge.setSource(source2);  
        bridge.method();  
    }  
}  

View Code

output:

this is the first sub!
this is the second sub!

然,就由此对Bridge类的调用,实现了对接口Sourceable的兑现类SourceSub1和SourceSub2的调用。接下来我再也打个图,大家就是应有亮了,因为是图是咱们JDBC连接的原理,有数据库学习基础之,一结合就还知道了。

图片 125

11、组合模式(Composite)

结合模式有时又给部分-整体模式在拍卖接近树形结构的题材时于便宜,看看关系图:

图片 126

直接来拘禁代码:

图片 127图片 128

public class TreeNode {  

    private String name;  
    private TreeNode parent;  
    private Vector<TreeNode> children = new Vector<TreeNode>();  

    public TreeNode(String name){  
        this.name = name;  
    }  

    public String getName() {  
        return name;  
    }  

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

    public TreeNode getParent() {  
        return parent;  
    }  

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

    //添加孩子节点  
    public void add(TreeNode node){  
        children.add(node);  
    }  

    //删除孩子节点  
    public void remove(TreeNode node){  
        children.remove(node);  
    }  

    //取得孩子节点  
    public Enumeration<TreeNode> getChildren(){  
        return children.elements();  
    }  
}  

View Code

图片 129图片 130

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");  

        nodeB.add(nodeC);  
        tree.root.add(nodeB);  
        System.out.println("build the tree finished!");  
    }  
}  

View Code

运用状况:将大半个目标组合在一起进行操作,常用于表示树形结构被,例如二叉树,数等。

12、享元模式(Flyweight)

享元模式之关键目的是落实目标的共享,即联名享池,当系统中目标多之时光可减少内存的开支,通常和工厂模式并下。

图片 131

FlyWeightFactory负责创建同管理享元单元,当一个客户端请求时,工厂急需检讨时目标池中是否来符合条件的目标,如果发生,就赶回就在的靶子,如果无,则开创一个新对象,FlyWeight是超类。一提到共享池,我们蛮容易联想到Java里面的JDBC连接池,想想每个连的风味,我们好总结发生:适用于作共享的组成部分单对象,他们发部分共有的习性,就用数据库连接池来说,url、driverClassName、username、password及dbname,这些性对于每个连来说还是一模一样的,所以就可用享元模式来处理,建一个厂子类,将上述接近性作为内部数据,其它的作为外部数据,在术调用时,当做参数传上,这样尽管节省了空中,减少了实例的多少。

扣押个例证:

图片 132

关押下数据库连接池的代码:

图片 133图片 134

public class ConnectionPool {  

    private Vector<Connection> pool;  

    /*公有属性*/  
    private String url = "jdbc:mysql://localhost:3306/test";  
    private String username = "root";  
    private String password = "root";  
    private String driverClassName = "com.mysql.jdbc.Driver";  

    private int poolSize = 100;  
    private static ConnectionPool instance = null;  
    Connection conn = null;  

    /*构造方法,做一些初始化工作*/  
    private ConnectionPool() {  
        pool = new Vector<Connection>(poolSize);  

        for (int i = 0; i < poolSize; i++) {  
            try {  
                Class.forName(driverClassName);  
                conn = DriverManager.getConnection(url, username, password);  
                pool.add(conn);  
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();  
            } catch (SQLException e) {  
                e.printStackTrace();  
            }  
        }  
    }  

    /* 返回连接到连接池 */  
    public synchronized void release() {  
        pool.add(conn);  
    }  

    /* 返回连接池中的一个数据库连接 */  
    public synchronized Connection getConnection() {  
        if (pool.size() > 0) {  
            Connection conn = pool.get(0);  
            pool.remove(conn);  
            return conn;  
        } else {  
            return null;  
        }  
    }  
}  

View Code

由此连接池的田间管理,实现了数据库连接的共享,不需要各一样坏都重新创设连接,节省了数据库重新创设的出,提升了网的性!本章讲解了7种植结构型模式,因为篇幅的题目,剩下的11栽行为型模式,

本章是关于设计模式的尾声一摆,会摆到第三种植设计模式——行为型模式,共11种植:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。这段时日一直于描绘关于设计模式的东西,终于写到一半了,写博文是个老费光阴的东西,因为自己得啊读者负责,不论是图或代码还是表达,都梦想能尽可能写清楚,以便读者知道,我怀念不管是本人要读者,都要观看大质量之博文出来,从自己自己出发,我会直接坚持下去,不断更新,源源动力来源于读者对象等的络绎不绝支持,我会始终自己之全力,写好各一样首文章!希望大家能源源给闹观点跟建议,共同制作全面的博文!

 

 

先行来张图,看看就11丁模式之涉嫌:

首先类:通过父类与子类的关联进展落实。第二看似:两独八九不离十中。第三像样:类的状态。第四近似:通过中类

图片 135

13、策略模式(strategy)

政策模式定义了一如既往多重算法,并以每个算法封装起来,使他们得以彼此替换,且算法的成形不见面影响到使用算法的客户。需要统筹一个接口,为同一密密麻麻实现类似提供合之章程,多个落实类似实现该接口,设计一个浮泛类(可有可无,属于辅助类),提供帮助函数,关系图如下:

图片 136

图中ICalculator提供同意的措施,
AbstractCalculator是辅助类,提供援助方法,接下去,依次实现产每个接近:

先是统一接口:

图片 137图片 138

public interface ICalculator {  
    public int calculate(String exp);  
}  

View Code

辅助类:

图片 139图片 140

public abstract class AbstractCalculator {  

    public int[] split(String exp,String opt){  
        String array[] = exp.split(opt);  
        int arrayInt[] = new int[2];  
        arrayInt[0] = Integer.parseInt(array[0]);  
        arrayInt[1] = Integer.parseInt(array[1]);  
        return arrayInt;  
    }  
}  

View Code

老三单实现类似:

图片 141图片 142

public class Plus extends AbstractCalculator implements ICalculator {  

    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"\\+");  
        return arrayInt[0]+arrayInt[1];  
    }  
}  

View Code

图片 143图片 144

public class Minus extends AbstractCalculator implements ICalculator {  

    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"-");  
        return arrayInt[0]-arrayInt[1];  
    }  

}  

View Code

图片 145图片 146

public class Multiply extends AbstractCalculator implements ICalculator {  

    @Override  
    public int calculate(String exp) {  
        int arrayInt[] = split(exp,"\\*");  
        return arrayInt[0]*arrayInt[1];  
    }  
}  

View Code

简单易行的测试类:

图片 147图片 148

public class StrategyTest {  

    public static void main(String[] args) {  
        String exp = "2+8";  
        ICalculator cal = new Plus();  
        int result = cal.calculate(exp);  
        System.out.println(result);  
    }  
}  

View Code

输出:10

方针模式之决定权在用户,系统本身提供不同算法的兑现,新增或去算法,对各种算法做封装。因此,策略模式多为此当算法决策系统被,外部用户仅仅待控制就此哪个算法即可。

14、模板方法模式(Template Method)

解释一下模板方法模式,就是指:一个泛类中,有一个兆方法,再定义1…n单道,可以是虚幻的,也可是实际上的点子,定义一个看似,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用,先押个关系图:

图片 149

即便以AbstractCalculator类中定义一个主方法calculate,calculate()调用spilt()等,Plus和Minus分别继承AbstractCalculator类,通过对AbstractCalculator的调用实现对子类的调用,看下面的例子:

图片 150图片 151

public abstract class AbstractCalculator {  

    /*主方法,实现对本类其它方法的调用*/  
    public final int calculate(String exp,String opt){  
        int array[] = split(exp,opt);  
        return calculate(array[0],array[1]);  
    }  

    /*被子类重写的方法*/  
    abstract public int calculate(int num1,int num2);  

    public int[] split(String exp,String opt){  
        String array[] = exp.split(opt);  
        int arrayInt[] = new int[2];  
        arrayInt[0] = Integer.parseInt(array[0]);  
        arrayInt[1] = Integer.parseInt(array[1]);  
        return arrayInt;  
    }  
}  

View Code

图片 152图片 153

public class Plus extends AbstractCalculator {  

    @Override  
    public int calculate(int num1,int num2) {  
        return num1 + num2;  
    }  
}  

View Code

测试类:

图片 154图片 155

public class StrategyTest {  

    public static void main(String[] args) {  
        String exp = "8+8";  
        AbstractCalculator cal = new Plus();  
        int result = cal.calculate(exp, "\\+");  
        System.out.println(result);  
    }  
}  

View Code

自家跟下者略带序的实行过程:首先以exp和”\\+”做参数,调用AbstractCalculator类里的calculate(String,String)方法,在calculate(String,String)里调用同类的split(),之后再行调用calculate(int
,int)方法,从者方式上到子类中,执行完return num1 +
num2后,将值返回到AbstractCalculator类,赋给result,打印出。正好说明了咱初步的笔触。

15、观察者模式(Observer)

包这模式在内的下一场的季只模式,都是近似及相近里的涉,不干到连续,学的时刻理应
记得归纳,记得本文最初步之良图。观察者模式很好明,类似于邮件订阅和RSS订阅,当我们浏览部分博客或wiki时,经常会看RSS图标,就即刻的意思是,当您订阅了拖欠篇,如果继续有更新,会立刻通报你。其实,简单来说话就同样词话:当一个靶变化时,其它依赖该目标的目标还见面接通知,并且随着变化!对象之间是同样种植同等对大多的关联。先来看望关系图:

图片 156

本身讲下这些近似的作用:MySubject类就是咱的预告对象,Observer1和Observer2是赖让MySubject的靶子,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义在要监控之靶子列表,可以本着那进展修改:增加或者删除被监督目标,且当MySubject变化时,负责通知在列表内设有的对象。我们看落实代码:

一个Observer接口:

图片 157图片 158

public interface Observer {  
    public void update();  
}  

View Code

简单独实现类似:

图片 159图片 160

public class Observer1 implements Observer {  

    @Override  
    public void update() {  
        System.out.println("observer1 has received!");  
    }  
}  

View Code

图片 161图片 162

public class Observer2 implements Observer {  

    @Override  
    public void update() {  
        System.out.println("observer2 has received!");  
    }  

}  

View Code

Subject接口及落实类似:

图片 163图片 164

public interface Subject {  

    /*增加观察者*/  
    public void add(Observer observer);  

    /*删除观察者*/  
    public void del(Observer observer);  

    /*通知所有的观察者*/  
    public void notifyObservers();  

    /*自身的操作*/  
    public void operation();  
}  

View Code

图片 165图片 166

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 del(Observer observer) {  
        vector.remove(observer);  
    }  

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

View Code

图片 167图片 168

public class MySubject extends AbstractSubject {  

    @Override  
    public void operation() {  
        System.out.println("update self!");  
        notifyObservers();  
    }  

}  

View Code

测试类:

图片 169图片 170

public class ObserverTest {  

    public static void main(String[] args) {  
        Subject sub = new MySubject();  
        sub.add(new Observer1());  
        sub.add(new Observer2());  

        sub.operation();  
    }  

}  

View Code

输出:

update self!
observer1 has received!
observer2 has received!

 这些东西,其实不碍事,只是微微不着边际,不极端容易整体理解,建议读者:据悉涉图,新建项目,自己写代码(或者参考我之代码),按照完整思路走相同整整,这样才会体会它的思想,理解起来容易! 

16、迭代子模式(Iterator)

顾名思义,迭代器模式就是是逐一访问聚集中的目标,一般的话,集合中异常常见,如果对集合类比较熟悉的话,理解仍模式会生自由自在。这词话包含两交汇意思:一凡是得遍历的对象,即集合对象,二凡迭代器对象,用于对聚集对象开展遍历访问。我们看下干图:

 图片 171

本条思路以及咱们经常因此的一律模型一样,MyCollection中定义了聚众的组成部分操作,MyIterator中定义了同等文山会海迭代操作,且富有Collection实例,我们来看望实现代码:

有数单接口:

图片 172图片 173

public interface Collection {  

    public Iterator iterator();  

    /*取得集合元素*/  
    public Object get(int i);  

    /*取得集合大小*/  
    public int size();  
}  

View Code

图片 174图片 175

public interface Iterator {  
    //前移  
    public Object previous();  

    //后移  
    public Object next();  
    public boolean hasNext();  

    //取得第一个元素  
    public Object first();  
}  

View Code

有限只落实:

图片 176图片 177

public class MyCollection implements Collection {  

    public String string[] = {"A","B","C","D","E"};  
    @Override  
    public Iterator iterator() {  
        return new MyIterator(this);  
    }  

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

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

View Code

图片 178图片 179

public class MyIterator implements Iterator {  

    private Collection collection;  
    private int pos = -1;  

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

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

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

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

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

}  

View Code

测试类:

图片 180图片 181

public class Test {  

    public static void main(String[] args) {  
        Collection collection = new MyCollection();  
        Iterator it = collection.iterator();  

        while(it.hasNext()){  
            System.out.println(it.next());  
        }  
    }  
}  

View Code

输出:A B C D E

这里我们一般模拟了一个集合类的进程,感觉是匪是非常爽朗?其实JDK中各个类为都是这些核心的物,加有设计模式,再加有优化放到一起的,只要我们管这些事物学会了,掌握好了,我们啊得以形容来自己的集合类,甚至框架!

17、责任链模式(Chain of Responsibility) 连片下去我们将要谈谈责任链模式,有差不多个目标,每个对象拥有对下一个目标的援,这样就会形成相同长链子,请求于就漫长链上传递,直到有一样对象说了算拍卖该要。但是发出者并无明了到底最终死目标会处理该要,所以,责任链模式可以兑现,在隐秘客户端的情状下,对网进行动态的调动。先看关系图:

 图片 182

 

Abstracthandler类提供了get和set方法,方便MyHandle类设置及修改引用对象,MyHandle类是主导,实例化后生成一名目繁多互动有的靶子,构成一长达链子。

 

图片 183图片 184

public interface Handler {  
    public void operator();  
}  

View Code

图片 185图片 186

public abstract class AbstractHandler {  

    private Handler handler;  

    public Handler getHandler() {  
        return handler;  
    }  

    public void setHandler(Handler handler) {  
        this.handler = handler;  
    }  

}  

View Code

图片 187图片 188

public class MyHandler extends AbstractHandler implements Handler {  

    private String name;  

    public MyHandler(String name) {  
        this.name = name;  
    }  

    @Override  
    public void operator() {  
        System.out.println(name+"deal!");  
        if(getHandler()!=null){  
            getHandler().operator();  
        }  
    }  
}  

View Code

图片 189图片 190

public class Test {  

    public static void main(String[] args) {  
        MyHandler h1 = new MyHandler("h1");  
        MyHandler h2 = new MyHandler("h2");  
        MyHandler h3 = new MyHandler("h3");  

        h1.setHandler(h2);  
        h2.setHandler(h3);  

        h1.operator();  
    }  
}  

View Code

输出:

h1deal!
h2deal!
h3deal!

这里强调一点即便是,链接上之乞求可以是一模一样漫漫链子,可以是一个栽培,还可是一个环抱,模式本身不束缚是,需要我们自己去落实,同时,在一个随时,命令就允许由一个目标传给任何一个目标,而休允许传被多只目标。

 18、命令模式(Command)

命令模式大好理解,举个例子,司令员下令让老将去干件事情,从全工作的角度来设想,司令员的图是,发出口令,口令经过传递,传至了战士耳朵里,士兵去执行。这个进程好当,三者相互解耦,任何一方都未用去因其他人,只需要做好协调的事务就是推行,司令员要之是结果,不见面去关爱到底士兵是怎么落实之。我们看关系图:

图片 191

Invoker是调用者(司令员),Receiver是为调用者(士兵),MyCommand是令,实现了Command接口,持有接收目标,看落实代码:

图片 192图片 193

public interface Command {  
    public void exe();  
}  

View Code

图片 194图片 195

public class MyCommand implements Command {  

    private Receiver receiver;  

    public MyCommand(Receiver receiver) {  
        this.receiver = receiver;  
    }  

    @Override  
    public void exe() {  
        receiver.action();  
    }  
}  

View Code

图片 196图片 197

public class Receiver {  
    public void action(){  
        System.out.println("command received!");  
    }  
}  

View Code

图片 198图片 199

public class Invoker {  

    private Command command;  

    public Invoker(Command command) {  
        this.command = command;  
    }  

    public void action(){  
        command.exe();  
    }  
}  

View Code

图片 200图片 201

public class Test {  

    public static void main(String[] args) {  
        Receiver receiver = new Receiver();  
        Command cmd = new MyCommand(receiver);  
        Invoker invoker = new Invoker(cmd);  
        invoker.action();  
    }  
}  

View Code

输出:command received!

本条非常哈理解,命令模式的目的就是是达命令的发出者和执行者之间解耦,实现请求和履行分开,熟悉Struts的同校应该知道,Struts其实就是是一致种将呼吁与显现分离之技巧,其中肯定涉及命令模式的思维!

其实每个设计模式都是充分重要之同种思想,看上去分外成熟,其实是以咱们以法到之事物吃还出涉嫌,尽管偶我们并不知道,其实以Java本身的计划性里处处都发生体现,像AWT、JDBC、集合类、IO管道或者是Web框架,里面设计模式无处不在。因为我们篇幅有限,很不便语各一个设计模式都谈的杀详细,不过我会尽我所能,尽量以片的空中和字数内,把意思写清楚了,更好为大家掌握。本章不出意外的语句,应该是设计模式最后一言了,首先还是达标转上篇开头的非常图:

图片 202

本章讲说第三接近及季接近。

19、备忘录模式(Memento)

重中之重目的是保留一个对象的某个状态,以便在适当的时段恢复对象,个人认为被备份模式再度形象来,通俗的讲下:假设有原始类A,A中生各种性能,A可以操纵用备份的性,备忘录类B是用来存储A的组成部分内部状态,类C呢,就是一个就此来储存备忘录的,且只能存储,不能够修改等操作。做只图来分析一下:

图片 203

Original类是原始类,里面来要保留之习性value及创建一个备忘录类,用来保存value值。Memento类是备忘录类,Storage类是储存备忘录的类,持有Memento类的实例,该模式特别好掌握。直接扣源码:

图片 204图片 205

public class Original {  

    private String value;  

    public String getValue() {  
        return value;  
    }  

    public void setValue(String value) {  
        this.value = value;  
    }  

    public Original(String value) {  
        this.value = value;  
    }  

    public Memento createMemento(){  
        return new Memento(value);  
    }  

    public void restoreMemento(Memento memento){  
        this.value = memento.getValue();  
    }  
}  

View Code

图片 206图片 207

public class Memento {  

    private String value;  

    public Memento(String value) {  
        this.value = value;  
    }  

    public String getValue() {  
        return value;  
    }  

    public void setValue(String value) {  
        this.value = value;  
    }  
}  

View Code

图片 208图片 209

public class Storage {  

    private Memento memento;  

    public Storage(Memento memento) {  
        this.memento = memento;  
    }  

    public Memento getMemento() {  
        return memento;  
    }  

    public void setMemento(Memento memento) {  
        this.memento = memento;  
    }  
}  

View Code

测试类:

图片 210图片 211

public class Test {  

    public static void main(String[] args) {  

        // 创建原始类  
        Original origi = new Original("egg");  

        // 创建备忘录  
        Storage storage = new Storage(origi.createMemento());  

        // 修改原始类的状态  
        System.out.println("初始化状态为:" + origi.getValue());  
        origi.setValue("niu");  
        System.out.println("修改后的状态为:" + origi.getValue());  

        // 回复原始类的状态  
        origi.restoreMemento(storage.getMemento());  
        System.out.println("恢复后的状态为:" + origi.getValue());  
    }  
}  

View Code

输出:

初始化状态也:egg
改后底状态呢:niu
复原后底状态吧:egg

简描述下:新建原始类时,value被初始化为egg,后经过改动,将value的值置为niu,最后倒数第二实践开展回复状态,结果成恢复了。其实自己道这模式为“备份-恢复”模式最像。

20、状态模式(State)

核心思想就是:当对象的状态改变时,同时更改其行事,很好理解!就以QQ来说,有几乎种状态,在线、隐身、忙碌等,每个状态对许不同的操作,而且若的相知也能够看到而的状态,所以,状态模式就是有限接触:1、可以由此改变状态来博取不同之作为。2、你的好友会而且来看您的变。看图:

图片 212

State类是独状态类,Context类可以兑现切换,我们来探代码:

图片 213图片 214

package com.xtfggef.dp.state;  

/** 
 * 状态类的核心类 
 * 2012-12-1 
 * @author erqing 
 * 
 */  
public class State {  

    private String value;  

    public String getValue() {  
        return value;  
    }  

    public void setValue(String value) {  
        this.value = value;  
    }  

    public void method1(){  
        System.out.println("execute the first opt!");  
    }  

    public void method2(){  
        System.out.println("execute the second opt!");  
    }  
}  

View Code

图片 215图片 216

package com.xtfggef.dp.state;  

/** 
 * 状态模式的切换类   2012-12-1 
 * @author erqing 
 *  
 */  
public class Context {  

    private State state;  

    public Context(State state) {  
        this.state = state;  
    }  

    public State getState() {  
        return state;  
    }  

    public void setState(State state) {  
        this.state = state;  
    }  

    public void method() {  
        if (state.getValue().equals("state1")) {  
            state.method1();  
        } else if (state.getValue().equals("state2")) {  
            state.method2();  
        }  
    }  
}  

View Code

测试类:

图片 217图片 218

public class Test {  

    public static void main(String[] args) {  

        State state = new State();  
        Context context = new Context(state);  

        //设置第一种状态  
        state.setValue("state1");  
        context.method();  

        //设置第二种状态  
        state.setValue("state2");  
        context.method();  
    }  
}  

View Code

输出:

 

execute the first opt!
execute the second opt!

根据此特点,状态模式于一般开销中的特别多的,尤其是召开网站的时,我们有时候想根据目标的之一同性能,区别开他们的组成部分效益,比如说简单的权柄决定相当。
21、访问者模式(Visitor)

访问者模式把数据结构和意向为组织及之操作解耦合,使得操作集合可相对自由地演变。访问者模式适用于数据结构相对稳定算法又轻变化的系。因为访问者模式让算法操作多变得好。若系统数据结构对象好变动,经常闹新的数额对象多进入,则不相符用访问者模式。访问者模式的优点是多操作特别轻,因为添操作表示增加新的访问者。访问者模式将有关行为集中到一个访问者对象被,其反不影响系数据结构。其症结就是长新的数据结构很拮据。——
From 百科

粗略来说,访问者模式就是是相同种分离对象数据结构与作为之办法,通过这种分离,可达到为一个被访问者动态增长新的操作而任由需做任何的改的效力。简单关联图:

图片 219

来探原码:一个Visitor类,存放要看的对象,

 

图片 220图片 221

public interface Visitor {  
    public void visit(Subject sub);  
}  

View Code

图片 222图片 223

public class MyVisitor implements Visitor {  

    @Override  
    public void visit(Subject sub) {  
        System.out.println("visit the subject:"+sub.getSubject());  
    }  
}  

View Code

Subject类,accept方法,接受将要访问它的靶子,getSubject()获取将要被拜的属性,

图片 224图片 225

public interface Subject {  
    public void accept(Visitor visitor);  
    public String getSubject();  
}  

View Code

图片 226图片 227

public class MySubject implements Subject {  

    @Override  
    public void accept(Visitor visitor) {  
        visitor.visit(this);  
    }  

    @Override  
    public String getSubject() {  
        return "love";  
    }  
}  

View Code

测试:

图片 228图片 229

public class Test {  

    public static void main(String[] args) {  

        Visitor visitor = new MyVisitor();  
        Subject sub = new MySubject();  
        sub.accept(visitor);      
    }  
}  

View Code

输出:visit the subject:love

拖欠模式适用场景:如果我们纪念为一个存活的类增加新力量,不得不考虑几个事情:1、新职能会不见面和存活功能出现兼容性问题?2、以后会无见面还用添加?3、如果类似非允修改代码怎么处置?面对这些题目,最好之缓解办法就是采取访问者模式,访问者模式适用于数据结构相对稳定性之网,把数据结构和算法解耦,
22、中介者模式(Mediator)

中介者模式也是故来降低类类之间的耦合的,因为要类类之间来依靠关系的讲话,不便利功能的拓及维护,因为只要修改一个对象,其它关联的目标都得进行改动。如果利用中介者模式,只需要关注与Mediator类的涉,具体类类之间的干及调度交给Mediator就行,这出接触像spring容器的作用。先看图:图片 230

User类统一接口,User1和User2分别是殊的对象,二者之间有关联合,如果未动中介者模式,则需要双方相互有引用,这样两边的耦合度很高,为了解耦,引入了Mediator类,提供合接口,MyMediator也实际现类,里面有User1和User2的实例,用来落实对User1和User2的控制。这样User1和User2鲜独对象相互独立,他们才待保障好与Mediator之间的干就行,剩下的全由MyMediator类来保安!基本实现:

图片 231图片 232

public interface Mediator {  
    public void createMediator();  
    public void workAll();  
}  

View Code

图片 233图片 234

public class MyMediator implements Mediator {  

    private User user1;  
    private User user2;  

    public User getUser1() {  
        return user1;  
    }  

    public User getUser2() {  
        return user2;  
    }  

    @Override  
    public void createMediator() {  
        user1 = new User1(this);  
        user2 = new User2(this);  
    }  

    @Override  
    public void workAll() {  
        user1.work();  
        user2.work();  
    }  
} 

View Code

图片 235图片 236

public abstract class User {  

    private Mediator mediator;  

    public Mediator getMediator(){  
        return mediator;  
    }  

    public User(Mediator mediator) {  
        this.mediator = mediator;  
    }  

    public abstract void work();  
}  

View Code

图片 237图片 238

public class User1 extends User {  

    public User1(Mediator mediator){  
        super(mediator);  
    }  

    @Override  
    public void work() {  
        System.out.println("user1 exe!");  
    }  
}  

View Code

图片 239图片 240

public class User2 extends User {  

    public User2(Mediator mediator){  
        super(mediator);  
    }  

    @Override  
    public void work() {  
        System.out.println("user2 exe!");  
    }  
}  

View Code

测试类:

图片 241图片 242

public class Test {  

    public static void main(String[] args) {  
        Mediator mediator = new MyMediator();  
        mediator.createMediator();  
        mediator.workAll();  
    }  
}  

View Code

输出:

user1 exe!
user2 exe!
23、解释器模式(Interpreter)
解释器模式是我们临时的末梢一叙,一般要采用在OOP开发中之编译器的开发被,所以适用面比较狭窄。

图片 243

Context类是一个上下文环境类,Plus和Minus分别是为此来测算的落实,代码如下:

图片 244图片 245

public interface Expression {  
    public int interpret(Context context);  
} 

View Code

图片 246图片 247

public class Plus implements Expression {  

    @Override  
    public int interpret(Context context) {  
        return context.getNum1()+context.getNum2();  
    }  
}  

View Code

图片 248图片 249

public class Minus implements Expression {  

    @Override  
    public int interpret(Context context) {  
        return context.getNum1()-context.getNum2();  
    }  
}  

View Code

图片 250图片 251

public class Context {  

    private int num1;  
    private int num2;  

    public Context(int num1, int num2) {  
        this.num1 = num1;  
        this.num2 = num2;  
    }  

    public int getNum1() {  
        return num1;  
    }  
    public void setNum1(int num1) {  
        this.num1 = num1;  
    }  
    public int getNum2() {  
        return num2;  
    }  
    public void setNum2(int num2) {  
        this.num2 = num2;  
    }  


}  

View Code

图片 252图片 253

public class Test {  

    public static void main(String[] args) {  

        // 计算9+2-8的值  
        int result = new Minus().interpret((new Context(new Plus()  
                .interpret(new Context(9, 2)), 8)));  
        System.out.println(result);  
    }  
}  

View Code

末尾输出正确的结果:3。

骨干就是这么,解释器模式用来开各种各样的解释器,如正则表达式等之解释器等等!

此文摘自:http://zz563143188.iteye.com/blog/1847029/

 

      《Windows Embedded Compact 7初体验》中一度简要介绍了该开条件之搭建,时隔一年,最近档遭到打算正式导入进来,于是要更搭建其开发环境。由于它们不克跟原先怀有版本的CE开发环境共存,之前是于虚拟机里设置之。要当路面临真正以,虚拟机的性远远不够,所以最好是安装双系统。Windows 7安装双系或相当便利,半独小时搞定。

     
俗话说,一回生二转熟,但次不好安装反而碰到了前未曾碰到的有些题材。装了系统后,先安装好VS2008,由于之前下载的SP1不知所踪,所以在另外一台网速较快之机上下充斥新的。在开发主机上安装常用软件如SVN、输入法还有360,并开启了Windows
Update。更新了系统,SP1也大半下充斥了。用UltraISO提取出来安装,漫长的等候上马了。不过当下早已来心理准备,当初设置VS2005之SP1时见识过。孰料,大概半独钟头后一点点回退了,安装失败。再来同样破,还是一如既往,错误提示也看不出什么名堂来,晕……前无异潮安装是老大顺利的,这拨是啃地了也?难道跟360关于?真是一失足成千古恨。重开下试,不行就重装系统了,心里都做好极端要命打算。结果还顺利完成!怀疑是Windows
Update的从,安装完毕所有补丁后尚未重启,直接设置VS2008之SP1可能会见起问题。如果下载一个集成SP1的VS2008,安装起来应当会省去成千上万年华,也会掉走这些弯路。

      Platform
Builder7.0底安本身非常简单。需要专注的是,7.0遭受除去Debug和Retail模式外,新增了Checked模式,多选设置一个架,会多占好几个G的长空,所以尽可能少选。以后在线更新补丁时为会见节省大量日和空间。我因在硬盘大一点,选择了有着ARM架构的,ARMv5、6暨7。安装完毕了后头,使用Windows
Embedded Developer Update
(WEDU)在线更新。这为是PB7.0改良的一个地方,6.0和之前的版需要交微软官网上去下载往年之全年续丁包和当下各月补丁包,还得按一定顺序安装。现在7.0免用那么辛苦了。

      Windows
Embedded Developer Update 的界面如下,可以选取创新至哪个版本。

图片 254

      选择创建offline
layout

图片 255

     
获取到履新包之高低图片 256

      开始更新

图片 257

图片 258

图片 259

图片 260

图片 261

      VS2008中Windows
Embedded Developer Update 所于的职

图片 262

     
由于网速所界定,下载更新一共花了2天时间,最后的offline
layout如下图所著,但愿下次装时亦可派上用场。

图片 263

     
总的来说,Windows Embedded Compact
7付出条件之立比较简单,注意以下几点即可

  • 安集成SP1的VS2008,省时间
  • 尽可能少选择一些零部件,省空间
  • 起足快之网络,真正享受Windows
    Embedded Developer Update (WEDU) 带来的便宜