创建型模式共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()); } }
结果

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· 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