创建型模式共5种(单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式)

创建型模式为了让对象的创建与使用分离!

 一、单例模式

1.饿汉式单例

复制代码
//饿汉式单例(一上来就给对象加载了)
public class Hungry {
    //可能会浪费空间
    private byte[] data1=new byte[1024*1024];
    private byte[] data2=new byte[1024*1024];
    private byte[] data3=new byte[1024*1024];
    private byte[] data4=new byte[1024*1024];
    private Hungry(){
    }
    private final static Hungry HUNGRY=new Hungry();
    public static Hungry getInstance(){
        return HUNGRY;
    }
} 
复制代码

2.懒汉式单例

复制代码
//懒汉式单例(单线程下确实ok,但是多线程并发时不行)
public class LazyMan {
    //5.防止同样是反射建的对象2和3不相同,使用标志位
    private static  boolean biaozhiwei=false;
    private LazyMan() {
        //4.防止反射破坏
        synchronized (LazyMan.class){
            //判断标志位
            if (biaozhiwei==false){
                biaozhiwei=true;
            }else {
                throw new RuntimeException("不要试图使用反射破坏异常");
            }
        }
        System.out.println(Thread.currentThread().getName() + "ok");
    }
    //volatile防止指令重排
    private volatile static LazyMan lazyMan;

    public static LazyMan getInstance() {
        //2.加锁(双重检测锁模式的懒汉式单例 简称DCL懒汉式)
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//不是一个原子性操作
                    /***
                     *   会发生的步骤
                     * 1.分配内存空间
                     * 2.执行构造方法,初始化对象
                     * 3.把这个对象指向这个空间
                     *(在lazyMan对象生成过程中,可能出现指令重排导致lazyMan是一个虚无的对象,需要加上volatile)
                     */
                }
            }
        }
        return lazyMan;
    }
    public static void main(String[] args) throws Exception  {
        //6.破坏标志位处理
        Field biaozhiwei = LazyMan.class.getDeclaredField("biaozhiwei");
        biaozhiwei.setAccessible(true);
        //3.反射可以破坏这种单例,instance和instance2值不相同
        LazyMan instance=LazyMan.getInstance();
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        LazyMan instance2 = declaredConstructor.newInstance();
        //2和3又不相同了
        biaozhiwei.set(instance2,false);
        LazyMan instance3 = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(instance2);
        System.out.println(instance3);
    }
    //1.多线程并发
//    public static void main(String[] args) {
//        for (int i=0;i<10;i++){
//            new Thread(()->{
//                LazyMan.getInstance();
//            }).start();
//        }
//    }
} 
复制代码

3.静态内部类

复制代码
//静态内部类
public class Holder {
    private Holder(){
    }
    public static Holder getInstance(){
        return InnerClass.HOLDER;
    }
    public static class InnerClass{
        private static final Holder HOLDER=new Holder();
    }
} 
复制代码

4.枚举

复制代码
//枚举本身也是一个class的类(反射不能破坏枚举)
public enum EnumSingle {
    INSTANCE;
    public EnumSingle getInstance(){
        return INSTANCE;
    }
}
class Test{
    public static void main(String[] args) throws Exception {
        EnumSingle instance1 = EnumSingle.INSTANCE;
        Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        EnumSingle instance3 = declaredConstructor.newInstance();
        EnumSingle instance2 = EnumSingle.INSTANCE;
        System.out.println(instance1);
        System.out.println(instance2);
        System.out.println(instance3);
    }
}
复制代码

二、工厂模式(实现了创建者和调用者分离)

核心:实例化对象不用new,用工厂方法代替,将调用者跟实现类进行解耦。

1.简单工厂模式(如果增加一个新的产品,你不修改代码做不到)

复制代码
//静态工厂模式(如果增加一个新的产品,你不修改代码做不到)
//不满足开闭原则
public class CarFactory {
    //方法一
    public static  Car getCar(String car){
        if (car.equals("五菱")){
            return new WuLing();
        }else if (car.equals("特斯拉")){
            return new Tesla();
        }else {
            return null;
        }
    }
    //方法二(优化)
    public static Car getWuLing(){
        return new WuLing();
    }
    public static Car getTesla(){
        return new Tesla();
    }
} 
复制代码

2.工厂方法模式(支持增加新产品)

复制代码
//工厂方法模式(Consumer类)
public class Consumer {
    public static void main(String[] args) {
        Car car = new WuLingFactory().getCar();
        Car car2 = new TeslaFactory().getCar();
        Car car3 = new MoBaiFactory().getCar();
        car.name();
        car2.name();
        car3.name();
    }
} 
复制代码
//五菱工厂类
public class WuLingFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new WuLing();
    }
}
//车工厂类
public interface CarFactory {
    Car getCar();
}
//车接口
public interface Car {
    void name();
}
//五菱类
public class WuLing implements Car {
    @Override
    public void name() {
        System.out.println("五菱宏光");
    }
}

三、抽象工厂模式(优:具体产品在应用层的代码隔离,无需关心创建的细节;缺:扩展新的产品困难,增加了系统的抽象性和理解难度)

//抽象生产工厂
public interface IProductFactory {
    //生产手机
    IphoneProduct iphoneProduct();
    //生产路由
    IRouterProduct routerProduct();
}

 四、建造者模式

作用:在用户不知道对象的建造和细节的情况下就可以直接创建复杂的对象

过程:工厂建零件=>建造组装=>用户使用

Builder类

复制代码
//抽象的建造者:方法
public abstract class Builder {
    abstract void buildA();
    abstract void buildB();
    abstract void buildC();
    abstract void buildD();
    //完工,得到产品
    abstract Product getProduct();
}
复制代码

Product类

复制代码
//产品:房子
public class Product {
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;

    public String getBuildA() {
        return buildA;
    }

    public void setBuildA(String buildA) {
        this.buildA = buildA;
    }

    public String getBuildB() {
        return buildB;
    }

    public void setBuildB(String buildB) {
        this.buildB = buildB;
    }

    public String getBuildC() {
        return buildC;
    }

    public void setBuildC(String buildC) {
        this.buildC = buildC;
    }

    public String getBuildD() {
        return buildD;
    }

    public void setBuildD(String buildD) {
        this.buildD = buildD;
    }

    @Override
    public String toString() {
        return "Product{" +
                "buildA='" + buildA + '\'' +
                ", buildB='" + buildB + '\'' +
                ", buildC='" + buildC + '\'' +
                ", buildD='" + buildD + '\'' +
                '}';
    }
}
复制代码

Worker类

复制代码
//具体的建造者:工人
public class Worker extends Builder{
    private Product product;
//重要
    public Worker() {
        product = new Product();
    }
    @Override
    void buildA() {
        product.setBuildA( "AAAA");
        System.out.println("AAAA");
    }
    @Override
    void buildB() {
        product.setBuildA( "BBBB");
        System.out.println("BBBB");
    }
    @Override
    void buildC() {
        product.setBuildA( "CCCC");
        System.out.println("CCCC");
    }
    @Override
    void buildD() {
        product.setBuildA( "DDDD");
        System.out.println("DDDD");
    }
    @Override
    Product getProduct() {
        return product;
    }
}
复制代码

Director类

复制代码
//指挥,核心,负责指挥构建一个工程,工程如何构建由他决定
public class Director {
    //可以指挥工人按照顺序建造
    public Product build(Builder builder){
        builder.buildA();
        builder.buildB();
        builder.buildC();
        builder.buildD();
        return builder.getProduct();
    }
} 
复制代码

Test类

复制代码
public class Test {
    public static void main(String[] args) {
        //指挥
        Director director = new Director();
        //指挥具体工人
        Product build = director.build(new Worker());
        System.out.println(build.toString());
    }
} 
复制代码

建造者模式(通过内部类)

Test类

复制代码
public class Test {
    public static void main(String[] args) {
        //服务员
        Worker worker = new Worker();
        //链式编程
        Product product = worker.buildA("全家桶").buildB("雪碧").getProduct();
        System.out.println(product.toString());
    }
} 
复制代码

Product类

复制代码
//产品
public class Product {
    private String BuildA="汉堡";
    private String BuildB="可乐";
    private String BuildC="薯条";
    private String BuildD="甜点";
    public String getBuildA() {
        return BuildA;
    }
    public void setBuildA(String buildA) {
        BuildA = buildA;
    }
    public String getBuildB() {
        return BuildB;
    }
    public void setBuildB(String buildB) {
        BuildB = buildB;
    }
    public String getBuildC() {
        return BuildC;
    }
    public void setBuildC(String buildC) {
        BuildC = buildC;
    }
    public String getBuildD() {
        return BuildD;
    }
    public void setBuildD(String buildD) {
        BuildD = buildD;
    }
    @Override
    public String toString() {
        return "Product{" +
                "BuildA='" + BuildA + '\'' +
                ", BuildB='" + BuildB + '\'' +
                ", BuildC='" + BuildC + '\'' +
                ", BuildD='" + BuildD + '\'' +
                '}';
    }
}
复制代码

Worker类

复制代码
public class Worker extends Builder{
    private Product product;
    public Worker() {
        product =new Product();
    }
    @Override
    Builder buildA(String msg) {
        product.setBuildA(msg);
        return this;
    }
    @Override
    Builder buildB(String msg) {
        product.setBuildB(msg);
        return this;
    }
    @Override
    Builder buildC(String msg) {
        product.setBuildC(msg);
        return this;
    }
    @Override
    Builder buildD(String msg) {
        product.setBuildD(msg);
        return this;
    }
    @Override
    Product getProduct() {
        return product;
    }
}
复制代码

Builder类

public abstract class Builder {
    abstract Builder buildA(String msg);
    abstract Builder buildB(String msg);
    abstract Builder buildC(String msg);
    abstract Builder buildD(String msg);
    abstract Product getProduct();
} 

五、原型模式(实现一个接口:Cloneable;重写一个方法:clone)

 Video类

复制代码
public class Video implements Cloneable{
    private String name;
    private Date createTime;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    public Video() {
    }
    public Video(String name, Date createTime) {
        this.name = name;
        this.createTime = createTime;
    }

    public String getName() {
        return name;
    }

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

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Video{" +
                "name='" + name + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}
复制代码

bilbil类

复制代码
//原型模式clone
public class bilbil {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date();
        Video v1 = new Video("feng",date);
        Video v2 = (Video) v1.clone();
        System.out.println(v1);
        System.out.println("v1--hash="+v1.hashCode());
        System.out.println(v2);
        System.out.println("v2--hash="+v2.hashCode());
    }
} 
复制代码

结果

 

 改造原型模式(浅拷贝=>深拷贝)

Video类

复制代码
public class Video implements Cloneable{
    private String name;
    private Date createTime;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //对clone方法进行改造
        Object obj = super.clone();
        Video v = (Video) obj;
        //将这个对象的属性也进行克隆(实现深克隆)
        v.createTime = (Date) this.createTime.clone();
        return obj;
    }
    public Video() {
    }
    public Video(String name, Date createTime) {
        this.name = name;
        this.createTime = createTime;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    @Override
    public String toString() {
        return "Video{" +
                "name='" + name + '\'' +
                ", createTime=" + createTime +
                '}';
    }
}
复制代码

bilbil类

复制代码
//解决原型模式clone后,修改原型,拷贝的也跟着变,浅拷贝改为深拷贝(对clone方法进行改造)
public class bilbil {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date();
        Video v1 = new Video("feng",date);
        Video v2 = (Video) v1.clone();
        System.out.println(v1);
        System.out.println(v2);
        System.out.println("--------------------------");
        date.setTime(43242424);
        System.out.println(v1);
        System.out.println("v1--hash="+v1.hashCode());
        System.out.println(v2);
        System.out.println("v2--hash="+v2.hashCode());
    }
} 
复制代码

结果

 

posted @   joyfulest  阅读(98)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示