A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 孤尽 于 2019-4-26 18:27 编辑

常用设计模式 Java 实现

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

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

设计模式六大原则
  • 开闭原则:开闭原则就是说对扩展开放,对修改关闭
  • 里氏代换原则:任何基类可以出现的地方,子类一定可以出现,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为
  • 依赖倒转原则:面对接口编程,依赖于抽象而不依赖于具体
  • 迪米特法则:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立
  • 合成复用原则:原则是尽量使用合成、聚合的方式,而不是使用继承



单例模式
什么是单例?
保证一个类只会创建一个实例
应用场景:
  • Winodw 任务管理器
  • Windows 回收站
  • 网站的在线人数计数器
  • 应用程序的日志应用
  • Web 应用配置对象的读取
  • 数据库连接池
  • 线程池
  • 文件系统
  • HttpApplication
运行时动态获取类信息

饿汉式
[Java] 纯文本查看 复制代码
/**
 * 饿汉式:
 *     类初始化时,会立即加载对象,线程天生安全,效率高
 */
public class User {
    // 存在方法区,不会回收
    private static User user = new User();
    private User() {
    }

    public User getInstance() {
        return user;
    }
懒汉式
[Java] 纯文本查看 复制代码
/**
 * 懒汉式:
 *     类初始化时,不会真正创建对象,只有使用时才真正创建对象
 */
public class User {

    private static User user;

    private User() {
    }

    public static synchronized User getInstance() {
        if (user == null)
            user = new User();
        return user;
    }
}
静态内部类
[Java] 纯文本查看 复制代码
/**
 * 静态内部类:
 *     兼顾了懒汉模式的内存优化(使用时才初始化)以及饿汉模式的安全性(不会被反射入侵)
 */
public class User {
    private User(){

    }

    static class SingletonClassInstance{
        private static final User user = new User();
    }

    public static User getInstance() {
        return SingletonClassInstance.user;
    }
}
枚举方式
[Java] 纯文本查看 复制代码
/**
 * 枚举:
 *     枚举天生就是单例,从JVM提供保障单例,避免反射,缺点没有延迟加载
 */
public class User {
    
    private User() {
    }

    public static User getInstance() {
        return SingletonUserEnum.INSTANCE.getInstance();
    }

    static enum SingletonUserEnum{
        INSTANCE;
        private User user;
        private SingletonUserEnum() {
            user = new User();
        }

        public User getInstance() {
            return this.user;
        }
    }
}
双重检验锁
[Java] 纯文本查看 复制代码
/**
 * 双重检验锁:
 *     线程安全的单例模式
 */
public class User {
    private String userName;
    private volatile static User3 user3;

    private User(){

    }

    public User getInstance(){
        if (user == null) {
            synchronized (this) {
                if (user == null){
                    user = new User();
                }
            }
        }
        return user;
    }
}
如何防止反射漏洞攻击?
在类里面增加一个 flag,初始值为 false,创建对象后更改为 true,如果为 true,就抛出异常
如何选择单例创建方式?
需要延迟加载,选择静态内部类、懒汉式
不需要延迟加载,选择枚举类、饿汉式
多线程应用首选双重检验锁

工厂模式

什么是工厂模式?
实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式
应用场景:
  • 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方
  • 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时
  • 设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口

简单工厂
[Java] 纯文本查看 复制代码
/**
 * 简单工厂相当于一个工厂有各种产品,用户无需知道具体产品的名称,只需要知道产品对应的参数即可
 * 缺点是类型过多不利于扩展维护 
 */
public class CarFactory {
    public static Car createrCar(String name) {
        if (name == null || name.equals(""))
            return null;
        if (name.equals("比亚迪"))
            return new BydCar();
        if (name.equals("吉利"))
            return new JiliCar();
        return null;
    }
}
工厂方法
[Java] 纯文本查看 复制代码
/**
 * 核心工厂不在负责所有产品的创建,而是将具体实现交给子类
 */
public interface CarFactory {
    Car createrCar(String name);
}

class BydFactory implements CarFactory {

    @Override
    public Car createrCar(String name) {
        return new BydCar();
    }
}

class JiliFactory implements CarFactory {
    @Override
    public Car createrCar(String name) {
        return new JiliCar();
    }
}
抽象工厂模式

什么是抽象工厂模式?
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂
该超级工厂又称为其他工厂的工厂,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供对象
应用场景:
  • QQ 换皮肤,一整套一起换
  • 生成不同操作系统的程序

[Java] 纯文本查看 复制代码
/**
 * 抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品
 */
public interface Engine {
    void run();
}

class EngineA implements Engine{

    @Override
    public void run() {
        System.out.println("发动机转速快");
    }
}

class EngineB implements Engine {

    @Override
    public void run() {
        System.out.println("发动机转速慢");
    }
}

public interface Chair {
    void run();
}

class ChairA implements Chair {

    @Override
    public void run() {
        System.out.println("自动加热");
    }
}

class ChairB implements Chair {

    @Override
    public void run() {
        System.out.println("不能加热");
    }
}

public interface CarFactory {
    // 创建发动机
    Engine createEngine();
    // 创建座椅
    Chair createChair();
}

public class JiliFactory implements CarFactory{

    @Override
    public Engine createEngine() {
        return new EngineA();
    }

    @Override
    public Chair createChair() {
        return new ChairA();
    }
}

简单工厂、工厂方法、抽象工厂小结
  • 简单工厂:用来生产同一等级结构中的任意产品
  • 工厂方法 :用来生产同一等级结构中的固定产品
  • 抽象工厂 :用来生产不同产品族的全部产品

摘自:https://yq.aliyun.com/articles/699195?spm=a2c4e.11157919.spm-cont-list.328.146c27aeDjkp55



更多图片 小图 大图
组图打开中,请稍候......

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马