23种设计模式之Java实现

本文详细介绍了23种设计模式的Java实现,包括单例、工厂、建造者、原型等创建型模式,以及适配器、代理、组合等结构型模式,还有责任链、策略等行为型模式。同时探讨了如何防止单例模式被反射和反序列化破解,并对各种模式进行了总结和应用场景分析。
摘要由CSDN通过智能技术生成

单例模式之饿汉式

class SingletonDemo1 {
    private static SingletonDemo1 instance = new SingletonDemo1() ;     //类初始化时,立即加载,天然线程安全

    private SingletonDemo1() {}     //私有化构造器

    public static SingletonDemo1 getInstance() {    //不需要同步,调用效率高
        return instance ;
    }
}

单例模式之懒汉式

class SingletonDemo2 {
    private static SingletonDemo2 instance = null ;     //类初始化时,不初始化这个对象,延迟加载,真正用的时候再创建

    private SingletonDemo2() {}     //私有化构造器

    public static synchronized SingletonDemo2 getInstance() {    //需要同步,调用效率低
        if(instance == null) {
            instance = new SingletonDemo2() ;
        }

        return instance ;
    }
}

单例模式之静态内部类实现

class SingletonDemo3 {
    //外部类初始化时,不会初始化这个静态类,延迟加载,真正用的时候再创建
    private static class SingletonClassInstance {
        //类初始化时,立即加载,天然线程安全
        private static final SingletonDemo3 instance = new SingletonDemo3() ;
    }

    private SingletonDemo3() {}     //私有化构造器

    //不需要同步,调用效率高
    public static SingletonDemo3 getInstance() {
        return SingletonClassInstance.instance ;
    }
}

单例模式之枚举实现

enum SingletonDemo4 {
    //枚举元素本身就是单例对象,由JVM保证,避免通过反射和反序列化的漏洞,但是不能延迟加载
    INSTANCE ;

    //根据需要,添加额外的操作
    public void singletonOperation() {

    }
}

**单例模式总结:**不需要延迟加载,枚举的方式好于饿汉式;需要延迟加载,静态内部类的方式好于懒汉式。
但是以上实现方式,除了 枚举 的方式外,其余都可以通过 反射反序列化 的方式破解。测试代码如下:

package JavaDesignPattern;

import java.io.*;
import java.lang.reflect.Constructor;

public class SingletonDemo {
    public static void main(String[] args) throws Exception {
        SingletonDemo1 s1 = SingletonDemo1.getInstance() ;
        SingletonDemo1 s2 = SingletonDemo1.getInstance() ;
        System.out.println(s1) ;
        System.out.println(s2) ;

        Class<SingletonDemo1> clazz = (Class<SingletonDemo1>)Class.forName("JavaDesignPattern.SingletonDemo1") ;
        Constructor<SingletonDemo1> c = clazz.getDeclaredConstructor(null) ;
        c.setAccessible(true) ;
        SingletonDemo1 s3 = c.newInstance() ;
        SingletonDemo1 s4 = c.newInstance() ;
        System.out.println(s3) ;
        System.out.println(s4) ;

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")) ;
        oos.writeObject(s1) ;
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")) ;
        SingletonDemo1 s5 = (SingletonDemo1) ois.readObject() ;
        System.out.println(s5) ;
    }
}

输出如下:

JavaDesignPattern.SingletonDemo1@56de9984
JavaDesignPattern.SingletonDemo1@56de9984
JavaDesignPattern.SingletonDemo1@3030d5aa
JavaDesignPattern.SingletonDemo1@561ba49d
JavaDesignPattern.SingletonDemo1@29e0969b

那么问题来了,如何避免通过 反射反序列化 的方式破解呢?解决方法如下:

class SingletonDemo1 implements Serializable{
    private static SingletonDemo1 instance = new SingletonDemo1() ;     //类初始化时,立即加载,天然线程安全


    private SingletonDemo1() {     //私有化构造器
        if(instance != null) {      //阻止反射
            throw new RuntimeException() ;
        }
    }

    public static SingletonDemo1 getInstance() {    //不需要同步,调用效率高
        return instance ;
    }

    //反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不是单独创建新对象。
    private Object readResolve() throws ObjectStreamException {
        return instance ;
    }
}

简单工厂模式(静态工厂模式)

interface Car{
    void run() ;
}

class Audi implements Car {
    @Override
    public void run() {
        System.out.println("奥迪!") ;
    }
}

class Byd implements Car {
    @Override
    public void run() {
        System.out.println("比亚迪~~") ;
    }
}

class CarFactory1{
    public static Car createCar(String type) {
        if(type.equals("奥迪")) {
            return new Audi() ;
        }else if(type.equals("比亚迪")) {
            return new Byd() ;
        }else {
            return null ;
        }
    }
}

工厂方法模式

interface Car{
    void run() ;
}

class Audi implements Car {
    @Override
    public void run() {
        System.out.println("奥迪!") ;
    }
}

class Byd implements Car {
    @Override
    public void run() {
        System.out.println("比亚迪~~") ;
    }
}

interface CarFactory2{
    Car createCar() ;
}

class AudiFactory implements CarFactory2 {
    @Override
    public Car createCar() {
        return new Audi() ;
    }
}

class BydFactory implements CarFactory2 {
    @Override
    public Car createCar() {
        return new Byd() ;
    }
}

抽象工厂模式

interface Motor {
    void run() ;
    void start() ;
}

class LuxuruMotor implements Motor {
    @Override
    public void run() {
        System.out.println("做功快!") ;
    }

    @Override
    public void start() {
        System.out.println("启动快,可以自动启停!") ;
    }
}

class LowMotor implements Motor {
    @Override
    public void run() {
        System.out.println("做功慢!") ;
    }

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


interface Seat{
    void massage() ;
}

class LuxurySeat implements Seat {
    @Override
    public void massage() {
        System.out.println("符合人体工程学,自动按摩!") ;
    }
}

class LowSeat implements Seat {
    @Override
    public void massage() {
        System.out.println("符合人体工程学,但不能自动按摩!") ;
    }
}


interface Tyre{
    void roll() ;
}

class LuxuryTyre implements Tyre {
    @Override
    public void roll() {
        System.out.println("耐磨!") ;
    }
}

class LowTyre implements Tyre {
    @Override
    public void roll() {
        System.out.println("容易磨损!") ;
    }
}


interface CarFactory3 {
    Motor createMotor () ;
    Seat createSeat() ;
    Tyre createTyre() ;
}

class LuxuryCarFactory implements CarFactory3 {
    @Override
    public Motor createMotor() {
        return new LuxuruMotor() ;
    }

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

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

class LowCarFactory implements CarFactory3 {
    @Override
    public Motor createMotor() {
        return new LowMotor() ;
    }

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

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

测试代码如下:

package JavaDesignPattern;

public class Factory {
    public static void main(String[] args) {
        Car c1 = CarFactory1.createCar("奥迪") ;
        Car c2 = CarFactory1.createCar("比亚迪") ;

        c1.run() ;
        c2.run() ;

        Car c3 = new AudiFactory().createCar() ;
        Car c4 = new BydFactory().createCar() ;
        c3.run() ;
        c4.run() ;

        Motor e = new LuxuryCarFactory().createMotor() ;
        e.run() ;
        e.start() ;
        Seat s = new LuxuryCarFactory().createSeat() ;
        s.massage() ;
        Tyre t = new LuxuryCarFactory().createTyre() ;
        t.roll() ;
    }
}

工厂模式总结:

  • 简单工厂模式又叫静态工厂模式,就是工厂类一般使用静态方法,通过接受参数的不同来返回不同的对象实例。对于新产品的增加,如果不修改已有源代码的话,是无法扩展的。虽然这违反了开闭原则(OCP),但是实际使用最多。
  • 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展。
  • 抽象工厂模式:不可以增加产品,只可以增加产品族。

建造者模式

class OrbitalModule {
    private String name ;

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

    public String getName() {
        return name ;
    }

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

class Engine {
    private String name ;

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

    public String getName() {
        return name ;
    }

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

class EscapeTower {
    private String name ;

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

    public String getName() {
        return name ;
    }

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

class AirShip {
    private OrbitalModule orbitalModule ;
    private Engine engine ;
    private EscapeTower escapeTower ;

    public void launch() {
        System.out.println("点火发射!") ;
    }

    public OrbitalModule getOrbitalModule() {
        return orbitalModule ;
    }

    public void setOrbitalModule(OrbitalModule orbitalModule) {
        this.orbitalModule = orbitalModule ;
    }

    public Engine getEngine() {
        return engine ;
    }

    public void setEngine(Engine engine) {
        this.engine = engine ;
    }

    public EscapeTower getEscapeTower() {
        return escapeTower ;
    }

    public void setEscapeTower(EscapeTower escapeTower) {
        this.escapeTower = escapeTower ;
    }
}

interface AirShipBuilder {
    OrbitalModule buildOrbitalModule() ;
    Engine buildEngine() ;
    EscapeTower buildEscapeTower() ;
}

class NASAAirShipBuilder implements AirShipBuilder {
    @Override
    public OrbitalModule buildOrbitalModule() {
        System.out.println("NASA轨道舱") ;
        return new OrbitalModule("NASA轨道舱");
    }

    @Override
    public Engine buildEngine() {
        System.out.println("NASA引擎") ;
        return new Engine("NASA引擎");
    }

    @Override
    public EscapeTower buildEscapeTower() {
        System.out.println("NASA逃逸塔") ;
        return new EscapeTower("NASA逃逸塔") ;
    }
}


interface AirShipDirector {
    AirShip directAirShip() ;
}

class NASAAirShipDirector implements AirShipDirector {

    private AirShipBuilder builder ;

    public NASAAirShipDirector(AirShipBuilder builder) {
        this.builder = builder;
    }

    @Override
    public AirShip directAirShip() {
        AirShip ship = new AirShip() ;
        ship.setOrbitalModule(builder.buildOrbitalModule()) ;
        ship.setEngine(builder.buildEngine()) ;
        ship.setEscapeTower(builder.buildEscapeTower()) ;

        return ship ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class Builder {
    public static void main(String[] args) {
        AirShip ship = new NASAAirShipDirector(new NASAAirShipBuilder()).directAirShip() ;
        System.out.println(ship.getEngine().getName()) ;
        ship.launch() ;
    }
}

**建造者模式总结:**实现了构建和装配的解耦。应用场景:某些对象的构建过程非常复杂。

原型模式

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值