设计模式(Java)


优快云博客地址 https://blog.youkuaiyun.com/weixin_47053123
Github项目下载地址https://github.com/MaBo2420935619


在这里插入图片描述

单例模式

饿汉模式

  • 像一个饿汉一样,不管需不需要用到实例都要去创建实例,即在类产生的时候就创建好实例,这是一种空间换时间的做法。作为一个饿汉而言,体现了它的本质——“我全都要”。
  • 对于饿汉模式而言,是线程安全的,因为在线程创建之前实例已经被创建好了。

代码演示

/**
 * @Author mabo
 * @Description   单例模式:饿汉式
 * @Description    在类初始化的时候,完成对属性的初始化
 * @Description    获取的对象是线程安全的
 */
 class SingletonHungry { 
     //构造方法私有化,防止new对象
     private SingletonHungry(){};
     
     private final static SingletonHungry singletonHungry=new SingletonHungry();
     
     public SingletonHungry getInstance(){
        return singletonHungry;
    }
    
     public static void main(String[] args) {
         for (int i = 0; i < 100; i++) {
            SingletonHungry singletonHungry = new SingletonHungry();
            SingletonHungry instance = singletonHungry.getInstance();
            System.out.println(instance.hashCode());
         }
     }
}

JDK Runtime实现源码

 public class Runtime {
        private static Runtime currentRuntime = new Runtime();
        public static Runtime getRuntime() {
            return currentRuntime;
        }
    }

懒汉模式

懒汉模式就是需要用到创建实例了程序再去创建实例,而不是JVM加载类的时候就创建好实例。
这里采用双重检验来提高代码执行效率,同时保证线程安全

public static SingletonLazy getInstance(){
        if (singletonLazy==null){
            synchronized (SingletonLazy.class){
                singletonLazy=new SingletonLazy();
            }
        }
        return singletonLazy;
    }

代码演示

/**
 * @Author mabo
 * @Description 单例模式:懒汉式,线程安全,双重检验初始化
 * @Description
 */
class SingletonLazy {
    //私有化构造器
    private SingletonLazy() {
    }

    private volatile static SingletonLazy singletonLazy;
    /**
     * @Author mabo
     * @Description 锁住方法体
     */
//    public static synchronized SingletonLazy getInstance(){
//        if (singletonLazy==null){
//            singletonLazy=new SingletonLazy();
//        }
//        return singletonLazy;
//    }

    /**
     * @Author mabo
     * @Description 锁住代码块,双重检查
     * @Description 此方法执行效率更高
     */

    public static SingletonLazy getInstance() {
        if (singletonLazy == null) {
            synchronized (SingletonLazy.class) {
                singletonLazy = new SingletonLazy();
            }
        }
        return singletonLazy;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            SingletonLazy instance = SingletonLazy.getInstance();
            System.out.println(instance.hashCode());
        }
    }
}

枚举实现单例模式

/**
 * @Author mabo
 * @Description   枚举实现单例模式
 */
public class SingletonEnum {
    enum Test {
        testEnum;

        public void sayTest() {
            System.out.println("我是枚举的方法");
        }

        public Test getTestEnum() {
            return testEnum;
        }
    }

    public static void main(String[] args) {
        Test test = Test.testEnum;
        Test test2 = Test.testEnum;
        test.sayTest();
        System.out.println(test.hashCode());
        System.out.println(test2.hashCode());
    }
}

工厂模式

为了下面的举例
创建两种食物:汉堡和鸡肉,都实现了Food接口

在这里插入图片描述

public interface Food {
    public void get();
}
public class Chicken implements Food{
    @Override
    public void get() {
        System.out.println("我要一份鸡肉");
    }
}
public class Hamburger implements Food {
    @Override
    public void get() {
        System.out.println("我要一份汉堡");
    }
}

简单工厂模式

简单工厂模式又称为静态工厂模式,实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
在这里插入图片描述
食物工厂,根据传入的参数,来决定返回什么类型的实例

public class FoodFactory {
    public static Food getFood(String type) throws InstantiationException, IllegalAccessException{
        if (type.equalsIgnoreCase("Chicken")) {
            return Chicken.class.newInstance();
        } else if (type.equalsIgnoreCase("Hamburger")) {
            return Hamburger.class.newInstance();
        } else {
            System.out.println("找不到相应的实例化类啦!"+type);
            return null;
        }
    }
}

方法工厂模式

  • 工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
  • 将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。

在这里插入图片描述

//创建食物工厂
public interface FoodFactory {
    public  Food getFood() throws InstantiationException, IllegalAccessException;
}
//创建鸡肉工厂
public class ChickenFactory implements FoodFactory{
    public  Food getFood() throws InstantiationException, IllegalAccessException {
        return Chicken.class.newInstance();
    }
}
//创建汉堡工厂
public class HamburgerFactory implements FoodFactory {
    public  Food getFood() throws InstantiationException, IllegalAccessException {
        return Hamburger.class.newInstance();
    }
}
//测试
public class MethodFactoryTest {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        FoodFactory factory=new ChickenFactory();
        Food food = factory.getFood();
        food.get();
        FoodFactory factory1=new HamburgerFactory();
        Food food1 = factory1.getFood();
        food1.get();
    }
}

原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

克隆

public class Student implements Cloneable {
    private String name;
    private int age;
    private Prototype prototype;

    public Student(String name, int age, Prototype prototype) {
        this.name = name;
        this.age = age;
        this.prototype = prototype;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", prototype=" + prototype +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Student clone = (Student)super.clone();
        return clone;
    }
}

测试

public class ShallowTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype prototype =new Prototype();
        Student student=new Student("mabo",20, prototype);
        Student student1 =(Student) student.clone();
        System.out.println(student);
        System.out.println(student.hashCode());
        System.out.println(student1);
        System.out.println(student1.hashCode());
        System.out.println(student==student1);
    }
}

序列化反序列化

public class Student implements Serializable{
    private String name;
    private int age;
    private Prototype prototype;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Student(String name, int age, Prototype prototype) {
        this.name = name;
        this.age = age;
        this.prototype = prototype;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", prototype=" + prototype +
                '}';
    }
    public Object deep(){
        //序列化反序列化进行深度拷贝
        ByteArrayOutputStream byteOut=null;
        ObjectOutputStream objOut=null;
        ByteArrayInputStream byteIn=null;
        ObjectInputStream objIn=null;
        try {
            //序列化
            byteOut=new ByteArrayOutputStream();
            objOut=new ObjectOutputStream(byteOut);
            objOut.writeObject(this);
            //反序列化
            byte[] bytes = byteOut.toByteArray();
            byteIn=new ByteArrayInputStream(bytes);
            objIn=new ObjectInputStream(byteIn);
            Student o =(Student) objIn.readObject();
            return o;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        finally {
            try {
                objIn.close();
                byteIn.close();
                objOut.close();
                byteOut.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

测试

public class ShallowTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype prototype =new Prototype();
        Student student=new Student("mabo",20, prototype);
        Student student1 =(Student) student.deep();
        System.out.println(student);
        System.out.println(student.hashCode());
        System.out.println(student1);
        System.out.println(student1.hashCode());
    }
}

建造者模式

建造者(Builder)模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成
下面以造车为例子,展示建造者模式

在这里插入图片描述
创建车的抽象类

public abstract class Car {
    public String color;
    public String size;

    public abstract void setColor();

    public abstract void setSize();

    @Override
    public String toString() {
        return "{" +
                "\"color\":\""+color+"\"," +
                "\"size\":\""+size+"\"" +

                "}";
    }
}

创建黑车

public class BlackCar extends Car{
    @Override
    public void setColor() {
        color="黑色";
    }

    @Override
    public void setSize() {
       size="四人座";
    }
}

创建红车

public class RedCar extends Car{
    @Override
    public void setColor() {
       color="红色";
    }

    @Override
    public void setSize() {
       size="双人坐";
    }
}

创建导购

public class Director {
    public Car getCar(Car car){
        car.setColor();
        car.setSize();
        return car;
    }
}

创建客人买车


public class Client {
    public static void main(String[] args) {
        Director director=new Director();
        Car car = director.getCar(new BlackCar());
        System.out.println("我买的车是"+car);
        car = director.getCar(new BlueCar());
        System.out.println("我买的车是"+car);
        car = director.getCar(new RedCar());
        System.out.println("我买的车是"+car);
    }
}

当客人需要一个蓝车,我们无需改动其他代码,只需要创建蓝车

public class BlueCar extends Car{
    @Override
    public void setColor() {
        color="蓝色";
    }

    @Override
    public void setSize() {
        size="单人";
    }
}

适配器模式

适配器模式可以分为类适配器,对象适配器,接口适配器。

以下只展示接口适配器模式
在这里插入图片描述
音乐播放器接口

public interface MusicPlayer {
    public void playMp3(String fileName);

    public void playM4(String fileName);

    public void playMav(String fileName);
}

MP3 格式适配器

public class Mp3Player implements MusicPlayer{
    @Override
    public void playMp3(String fileName) {
        System.out.println("播放mp3文件"+fileName);
    }

    @Override
    public void playM4(String fileName) {

    }

    @Override
    public void playMav(String fileName) {

    }
}

MP4格式适配器

public class Mp4Player implements MusicPlayer{
    @Override
    public void playMp3(String fileName) {

    }

    @Override
    public void playM4(String fileName) {
        System.out.println("播放mp4文件"+fileName);
    }

    @Override
    public void playMav(String fileName) {

    }
}

mav格式适配器

public class MavPlayer implements MusicPlayer {
    @Override
    public void playMp3(String fileName) {

    }

    @Override
    public void playM4(String fileName) {

    }

    @Override
    public void playMav(String fileName) {
        System.out.println("播放mav文件" + fileName);
    }
}

播放接口

public interface PlayMusic {
    void playMusic(String fileName);
}

音乐适配器


public class MusicAdapter implements PlayMusic {
    private MusicPlayer musicplayer;

    private void getPlayer(String fileName) {
        if (fileName.equals("mp3")) {
            musicplayer = new Mp3Player();
        } else if (fileName.equals("mp4")) {
            musicplayer = new Mp4Player();
        } else if (fileName.equals("mav")) {
            musicplayer = new MavPlayer();
        } else {
            System.out.println("找不到适配器");
        }
    }

    @Override
    public void playMusic(String fileName) {
        getPlayer(fileName);
        if (musicplayer != null) {
            musicplayer.playMp3(fileName);
            musicplayer.playM4(fileName);
            musicplayer.playMav(fileName);
        }
        musicplayer = null;
    }
}

客户使用

public class Client {
    public static void main(String[] args) {
        MusicAdapter musicAdapter = new MusicAdapter();
        musicAdapter.playMusic("mp3");
        musicAdapter.playMusic("mp4");
        musicAdapter.playMusic("mav");
        musicAdapter.playMusic("23");
    }
}

测试结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值