写这篇文章的目的主要是为了纪录学习的,然后查漏补缺,欢迎指正。文章如果有发现引用他人的名言警句,不要慌张,给我留言,毕竟站在伟人的肩膀上。

设计模式GOF23(group of four)

前言:

在软件中,模式是帮助人类向“变化”战斗,但是在软件中还需要和“变化”直接面对面战斗的武器:人的思维,特别是创造,分析思维等等,这些是软件真正的灵魂,这种思维可以说只要有实践需求(如有新项目)就要求发生,发生频度高,人类的创造或者分析思维决定了软件的质量合和特点。

而在建筑中,模式可以构成建筑全部只是,当有新的需求(如有新的项目),一般使用旧的模式都可以完成,因此对人类的创造以及分析思维不是每个项目都必须的,也不是非常重要的,对创造性的思维的需求只是属于锦上添花(除非人类以后离开地球居住了)。

以上两段是借鉴他人的,具体摘抄信息无法提供,不过如果我有引用到您的成果,请联系我。

设计模式有以下类型:

创建型模式:

-单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。

结构型模式:

-适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

行为型模式:

-模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

一、设计模式之单例模式

核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。

常见应用场景:

--Windows的Task Manager(任务管理器)就是很典型的单例模式;(由一个对象组成的,不管你启动多少个任务管理器,页面显示只会有一个)

--windows的回收站,也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例

--项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,每次new一个对象去读取

--网站的计数器,一般也是采用单例模式实现,否则难以同步

--应用程序的日志应用,一般都可用单例模式实现。这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加

--数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源

--操作系统的文件系统,也是采用的单例模式实现的及具体例子,一个操作系用只能有一个文件系统

--Application也是单例的典型应用(Servlet变成中会涉及到)

--在Spring中,每个Bean默认就是单例的,这样做的有点是Spring容器可以管理

--在servlet编程中,每个Servlet也是单例

--在spring MVC框架/struts1框架中,控制器对象也是单例

--常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。

单例模式的优点:

--由于单例模式只生成一个实例,减少了系统性能开销(限制实例个数,节省了内存,利于java垃圾回收(garbage collection)),当一个对象的产生需要比较多的资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决

--单例模式可以在系统设置全局的访问点,优化环境共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理

常见的五种单例模式实现方式:

--主要:

饿汉式(线程安全,调用效率高。但是,不能延时加载。)

懒汉式(线程安全,调用效率不高,但是,可以延时加载。)

--其他:

双重检测锁式(由于JVM底层内部模型原因,偶尔会出现问题。不建议使用)

静态内部类式(线程安全,调用效率高,可以延时加载)

枚举单例(线程安全,调用效率高,不能延时加载)

代码:

① 饿汉式

public class Singleton(){

    private Singleton(){};//私有构造器


    private static Singleton instance= new Singleton();//在自己内部定义一个实例

    public static Singleton getInstance(){//创建一个访问方法

        return instance;

    }

}

② 懒汉式

public class LazeSingleton(){

    private LazeSingleton(){} ;//私有构造方法

    private static LazeSingleton instance; //创建私有变量

    public static synchronized LazeSingleton getInstance(){

        //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次

        //使用时生成实例,提高了效率

        if(instance==null){

            return instance = new LazeSingleton();

        }else{

            return instance;

        }

    }

}

比较上述两个单例模式:

相同点:都是通过getInstance()可以访问单态类;

不同点:

a.第一种是饿汉式,不管三七二十一,不管对象用不用,上面就new;第二种是懒汉式,用的时候才new,并且new一次,无需再new,节省资源开支,减少了内存的使用;

b.第一种中没有使用synchronized,这个关键词在第二种方法中很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个LazeSingleton实例。

c.一般认为第一种形式更加安全些。

二、设计模式之工厂模式(Factory)

工厂模式定义:实现了创建者和调用者的分离。

详细分类:

简单工厂模式

工厂方法模式

抽象工厂模式

面向对象大合集的基本原则:

OCP (开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭;

DIP (依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程;

LOD (迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信。

核心本质:

实例化对象,用工厂方法代替new操作。

将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。

工厂模式:

简单工厂模式:用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有的代码)

工厂方法模式:用来生产同一等级结构中的固定产品。(支持增加任意产品)

抽象工厂模式:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

简单工厂模式代码:
接口:
/**
 * @author happy
 * time goes by without time.
 */
public interface Car {
    void run();
}
bean类:
/**
 * @author happy
 * time goes by without time.
 */
public class AuDi implements Car{
    @Override
    public void run() {
        System.out.println("this is AoDi.");
    }
}

public class HaFo implements Car {
    @Override
    public void run() {
        System.out.println("this is HaFo.");
    }
}
public class SimpleFactory {
    public static Car createFactory(String a){
        if ("AoDi"==a){
            return new AuDi();
        }else if ("HaFo"==a){
            return new HaFo();
        }else
        return null;
    }
}
//主方法
public class Factory {
    public static void main(String[] args) {
        Car c1 = SimpleFactory.createFactory("AoDi");
        c1.run();
    }
}

小结:简单工厂模式也叫静态工厂模式,就是工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。项目开发中,通常多使用简单工厂模式。不修改代码的话,是无法扩展的,与开闭原则冲突。

工厂方法模式代码:
//其它的bean类与上面简单工厂模式相同
//工厂方法:每个牌子的汽车创建一个工厂类

public interface CarFactory {
    Car createCar();
}

public class HaFoFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new HaFo();
    }
}

public class Client {
    public static void main(String[] args) {
        Car c1 = new HaFoFactory().createCar();
        c1.run();
    }
}

小结:较简单工厂模式:结构复杂度提高(类增多);代码复杂度提高(代码复杂);客户端编程难度提高(需要实例化);管理难度上,工厂方法模式完全满足OCP,但是为了满足其扩展性,要用增加类,提高代码复杂度和客户端编程难度为前提。理论上采用,工厂方法模式。但实际上开发中,我们一般采用简单工厂模式。

代码:
/**
 * @author happy
 * time goes by without time.
 */
public interface Engine {
    void run();
    void start();
}
 class LuxuryEngine implements Engine{
     @Override
     public void run() {
        System.out.println("力气大!");
     }

     @Override
     public void start() {
         System.out.println("启动快!");
     }
 }
class LowerEngine implements Engine{
    @Override
    public void run() {
        System.out.println("力气小!");
    }

    @Override
    public void start() {
        System.out.println("启动慢!");
    }
}


/**
 * @author happy
 * time goes by without time.
 */
public interface Seat {
    void massage();
}
class LuxurySeat implements Seat{
    @Override
    public void massage() {
        System.out.println("做起来舒服!");
    }
}
class LowerSeat implements Seat{
    @Override
    public void massage() {
        System.out.println("做起来不舒服!");
    }
}

/**
 * @author happy 
 * time goes by without time.
 */
public interface Tyre {
    void revolve();
}
class LuxuryTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("跑的远!");
    }
}
class LowerTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("跑的不远!");
    }
}

/**
 * @author happy
 * time goes by without time.
 */
public interface CarFactory {
    Engine createEngine();
    Seat createSeat();
    Tyre createTyre();
}


/**
 * @author happy 
 * time goes by without time.
 */
public class LuxuryCarFactory implements CarFactory {
    @Override
    public Engine createEngine() {
        return new LuxuryEngine();
    }

    @Override
    public Seat createSeat() {
        return new LuxurySeat();
    }

    @Override
    public Tyre createTyre() {
        return new LuxuryTyre();
    }
}

/**
 * @author happy 
 * time goes by without time.
 */
public class LowerCarFactory implements CarFactory {
    @Override
    public Engine createEngine() {
        return new LowerEngine();
    }

    @Override
    public Seat createSeat() {
        return new LowerSeat();
    }

    @Override
    public Tyre createTyre() {
        return new LowerTyre();
    }
}

/**
 * @author happy
 * time goes by without time.
 */
public class Client {
    public static void main(String[] args) {
       CarFactory fac1 = new LuxuryCarFactory();
        fac1.createEngine().run();
        fac1.createSeat().massage();
        fac1.createTyre().revolve();
    }
}

小结:抽象工厂模式要点:简单工厂模式(静态工厂模式)虽然某种程度不符合设计原则,但实际使用最多;工厂方法模式不修改已有类的前提下,通过增加新的工厂类实现扩展;抽象工厂模式不可以增加产品,可以增加产品族!应用场景(多):

--jdk中Calendar的getInstance方法

--JDBC中Connection对象的获取

--spring中IOC容器创建管理bean对象

--反射中Class对象的newInstance()

--XML解析时的DocumentBuilderFactory创建解析器对象

更多推荐

Java中23中设计模式