20.Java设计模式

来源:互联网 发布:淘宝旗舰店买手机 编辑:程序博客网 时间:2024/06/03 21:48
20.Java设计模式
转载请保留原文链接: http://dashidan.com/article/java/basic/Java设计模式.html

软件设计领域的四位世界级大师Gang Of Four (GoF):Erich Gamma, Richard Helm, Ralph Johnson,John Vlissides合著了一本非常著名的书《Design Patterns - Elements of Reusable Object-Oriented Software》翻译的中文名为《设计模式:可复用面向对象软件的基础》.书中提出了23种基本设计模式,从理论高度提炼并规范了设计模式,对面向对象软件设计产生了巨大影响.

19-1

① 设计模式简介

总体来说设计模式分为三大类:
创建型模式,共五种:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式.
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式.
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式.

有些设计模式我个人认为,不是很具象, 就像星座一样抽象概念居多,导致应用场景不明确. 所以不希望他们占用我过多的脑容量和时间.只挑选几个含金量高, 模型具象, 应用场景广泛的模式来介绍. 以下这几个都是非常值得花时间去熟悉的模式.

② 单例模式

单例模式即是只产生一个对象的模式.在Java中,每次使用new关键字, 就会产生一个新的对象. 有时我们需要只有一个对象产生, 比如一些管理类, 全局管理其它模块时, 这个管理类适合采用单例模式.

普通的单例模式分为2种, 懒汉式和饿汉式.懒汉式比较懒, 用到的时候才创建对象, 饿汉式不讲理, 你用不用我都创建好放着.

secret

普通单例模式的秘籍:
* 将构造函数定义为私有private, 只能在本类中创建, 不能被继承.
* 通过privatestatic关键字定义一个私有并且静态的本类实例对象, 保证内存中只有1个实例, 并且只有本类能调用.
* 公开一个获得本类实例的静态方法, 来获取这个实例, 保证每次得到的实例都是同一个, 来实现单例模式.

列出4种常用的单例模式的写法, 推荐第4种. 第4种是通过内部类实现, 高效且线程安全. 记住这个好了, 其他的可以忘.

1.懒汉式

/** * 懒汉式单例模式 */class Singleton1 {    private static Singleton1 singleton1;    private Singleton1() {    }    public static Singleton1 getInstance() {        if (null == singleton1) {            singleton1 = new Singleton1();        }        return singleton1;    }}

2.饿汉式

/** * 饿汉式单例模式 */class Singleton2 {    private static Singleton2 singleton2 = new Singleton2();    private Singleton2() {    }    public static Singleton2 getInstance() {        return singleton2;    }}

3.线程安全的懒汉式

/** * 线程安全懒汉式单例模式 */class Singleton3 {    private static Singleton3 singleton3;    private Singleton3() {    }    public static synchronized Singleton3 getInstance() {        if (null == singleton3) {            singleton3 = new Singleton3();        }        return singleton3;    }}

4.内部类线程安全单例模式

这种方式利用java的final关键字特性, 一旦赋值无法改变.线程安全,效率高推荐方式.

/** * 内部类线程安全单例模式 */class Singleton4 {    private static class SingletonHolder {        public final static Singleton4 instance = new Singleton4();    }    public static Singleton4 getInstance() {        return SingletonHolder.instance;    }}

③ 工厂模式

工厂模式本质是通过条件语句,根据不同的条件创建不同的对象.通常情况下, 产生的对象继承自同一个父类, 工厂类提供的方法返回的类型为父类对象类型.达到对象封装的作用.

代码示例:

package com.dashidan.lesson19;/** * 大屎蛋教程网-dashidan.com * <p> * Java教程基础篇:  19.Java设计模式 * 工厂模式 */public class Demo2 {    public static void main(String[] args) {        /** 传入需要生产的产品类型*/        Product product = Factory.getProduct(1);        /** 打印产品信息*/        product.info();    }}/** * 工厂模式 * 根据不同的类型,生产不同的产品 */class Factory {    public static Product getProduct(int type) {        switch (type) {            case 1:                return new Product1();            case 2:                return new Product2();        }        return null;    }}/** * 产品的父类是抽象类,提供一个info方法 */abstract class Product {    public abstract void info();}/** * 产品Product1继承自父类Product */class Product1 extends Product {    @Override    public void info() {        System.out.println("Product1 info.");    }}/** * 产品Product2继承自父类Product */class Product2 extends Product {    @Override    public void info() {        System.out.println("Product2 info.");    }}

输出:

Product1 info.

④ 观察者模式

观察者模式(也称为发布(publish)-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式).是一个非常棒的降低代码耦合度的方式.

secret

观察者模式的秘籍:
* 观察者在发布者对象上注册消息侦听, 加入消息侦听列表
* 发布者遍历消息侦听列表, 调用观察者方法处理消息
* 不同的观察者对象通常继承同一个观察者接口, 通过接口方法统一处理

通常用在一对多或者多对多的场景中, 一个对象数据变化了, 需要通知其他对象的场景. 比如ActionScript3语言底层的事件冒泡机制, 就是采用观察者模式设计.

代码示例:

package com.dashidan.lesson19;import java.util.ArrayList;/** * 大屎蛋教程网-dashidan.com * <p> * Java教程基础篇:  19.Java设计模式 * 观察者模式 */public class Demo3 {    public static void main(String[] args) {        /** 初始化发布者和观察者*/        Publisher publisher = new Publisher();        Observer1 observer1 = new Observer1();        Observer2 observer2 = new Observer2();        /** 加入2个观察者到发布者的消息侦听队列*/        publisher.addObserver(observer1);        publisher.addObserver(observer2);        /** 通知观察者*/        publisher.notifyAllObserver();    }}/** * 发布者 */class Publisher {    /**     * 发布者的消息侦听队列     */    ArrayList<IObserver> observers = new ArrayList<>();    /**     * 加入消息侦听队列     */    public void addObserver(IObserver iObserver) {        System.out.println("加入观察者");        observers.add(iObserver);    }    /**     * 通知侦听队列中所有的观察者     */    public void notifyAllObserver() {        for (IObserver iObserver : observers) {            System.out.println("通知观察者");            iObserver.action();        }    }}/** * 观察者接口 */interface IObserver {    void action();}/** * 观察者Observer1类 */class Observer1 implements IObserver {    @Override    public void action() {        System.out.println("Observer1 action.");    }}/** * 观察者Observer2类 */class Observer2 implements IObserver {    @Override    public void action() {        System.out.println("Observer2 action.");    }}

输出:

加入观察者加入观察者通知观察者Observer1 action.通知观察者Observer2 action.

⑤ 相关文章

Java从入门到精通目录

Java集成开发环境