创建型设计模式
单例模式
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。
饿汉模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
这种方式比较常用,没有加锁,执行效率会提高。类加载时就初始化,浪费内存,但容易产生垃圾对象。
懒汉模式
- 第一种
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
这是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。
- 第二种
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
这种方式能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
- 第三种
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
静态内部类
直接上代码吧
public class Singleton {
private Singleton (){}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
第一次加载Singleton类的时候并不会初始化INSTANCE ,只有在调用 getInstance()才会初始化。
枚举
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
工厂模式
工厂模式包含以下几个主要角色:
- 抽象产品(Abstract Product):定义了产品的共同接口或抽象类。
- 具体产品(Concrete Product):实现了抽象产品接口的子类。
- 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,它可以有多个方法用于创建不同类型的产品。
- 具体工厂(Concrete Factory):实现了抽象工厂接口的子类
简单工厂模式
简单工厂模式是工厂模式的基础。它使用一个单独的工厂类来创建不同的对象,根据传入的参数决定创建哪种类型的对象。
- 抽象产品
public abstract class phone {
public abstract void call();
}
- 具体产品
public class XiaoMi implements phone {
@Override
public void call() {
System.out.println("XiaoMi Call");
}
}
public class OPPO implements phone {
@Override
public void call() {
System.out.println("OPPO Call");
}
}
public class HuaWei implements phone {
@Override
public void call() {
System.out.println(" HuaWei Call");
}
}
- 具体工厂
public class PhoneFactory {
//使用getPhone 方法获取电话类型的对象
public phone getPhone (String phoneType){
if(phoneType == null){
return null;
}
if(phoneType.equalsIgnoreCase("XiaoMi")){
return new XiaoMi();
} else if(phoneType.equalsIgnoreCase("OPPO")){
return new OPPO();
} else if(phoneType.equalsIgnoreCase("HuaWei")){
return new HuaWei();
}
return null;
}
}
- 运行
public class FactoryPhone {
public static void main(String[] args) {
PhoneFactory phoneFactory = new PhoneFactory ();
//获取XiaoMi的对象,并调用它 call方法
phone XiaoMi = phoneFactory.getPhone("XiaoMi");
XiaoMi .call();
//获取OPPO的对象,并调用它的call方法
phone OPPO= phoneFactory.getPhone("OPPO");
OPPO.call();
//获取HuaWei的对象,并调用它的call方法
phone HuaWei= phoneFactory.getPhone("HuaWei");
HuaWei.call();
}
}
工厂方法模式
工厂方法模式定义了一个创建对象的接口,由子类决定实例化哪个类。工厂方法将对象的创建延迟到子类。
- 抽象产品
public abstract class phone {
public abstract void call();
}
- 具体产品
public class XiaoMi implements phone {
@Override
public void call() {
System.out.println("XiaoMi Call");
}
}
public class OPPO implements phone {
@Override
public void call() {
System.out.println("OPPO Call");
}
}
- 抽象工厂
public abstract class phoneFactory{
public abstract phone createPhone();
}
- 具体工厂
public class XiaoMiFactory implements phoneFactory{
@Override
public phone createPhone() {
return new XIaoMi();
}
}
public class OPPOFactory implements phoneFactory{
@Override
public phone createPhone() {
return new OPPO();
}
}
- 运行
XiaoMiFactory xmFac = new XiaoMiFactory();
xmFac.createPhone();
OPPOFactory oppoFac = new OPPOFactory();
oppoFac .createPhone();
建造者模式
建造者模式主要目的是将一个复杂对象的构建过程与其表示相分离,从而可以创建具有不同表示形式的对象。就好比去吃肯德基,汉堡、可乐、薯条、炸鸡等是不变的,而其组合是经常变化的,生成出不同的"套餐"。
建造者模式包含以下几个主要角色:
- 产品(Product):要构建的复杂对象。产品类通常包含多个部分或属性。
- 抽象建造者(Builder):定义了构建产品的抽象接口,包括构建产品的各个组成部分的方法。
- 具体建造者(Concrete Builder):实现抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。
- 指导者(Director):负责调用建造者的方法来构建产品,指导者并不了解具体的构建过程,只关心产品的构建顺序和方式。
- 产品
public class Phone{
private String screen;
private String cpu;
public String getScreen() {
return screen;
}
public void setScreen(String screen) {
this.screen= screen;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu= cpu;
}
}
- 抽象建造者
public abstract class Builder {
//这里只是一个空壳,还需要具体实现
Phone phone = new Phone();
//手机的组成部分
public abstract void buildScreen();
public abstract void buildCpu();
//构建手机
public abstract Phone createPhone();
}
- 具体建造者类
public class HUAWEIBuilder extends Builder{
@Override
public void buildScreen() {
this.phone.setScreen("不知道什么类型");
}
@Override
public void buildCpu() {
this.phone.setCpu("麒麟");
}
@Override
public Phone createPhone() {
return this.phone;
}
}
public class QualcommBuilder extends Builder{
@Override
public void buildScreen() {
this.phone.setScreen("不知道什么类型");
}
@Override
public void buildCpu() {
this.phone.setCpu("骁龙");
}
@Override
public Phone createPhone() {
return this.phone;
}
}
- 指导者
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public Phone construct() {
builder.buildScreen();
builder.buildCpu();
return builder.createPhone();
}
}
- 运行
public class Client {
public static void main(String[] args) {
makePhone(new HUAWEIBuilder());
makePhone(new QualcommBuilder());
}
private void makePhone(Builder builder) {
Director director = new Director(builder);
Phone phone = director.construct();
System.out.println(phone.getScreen());
System.out.println(phone.getCpu());
}
}
建造者模式扩展:链式编程底层
当一个类构造器需要传入多个参数,此时创建这个类的实例,代码的可读性就会非常差,而且很容易引入新的错误. 此时就可以使用 链式编程底层 的方式对 建造者模式进行重构。
public class Phone {
private String cpu;
private String screen;
private String memory;
//**私有构造,只对内提供**
private Phone(Builder builder) {
this.cpu = builder.cpu;
this.screen = builder.screen;
this.memory = builder.memory;
}
//重点**链式编程构建**
public static class Builder {
private String cpu;
private String screen;
private String memory;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder screen(String screen) {
this.screen = screen;
return this;
}
public Builder memory(String memory) {
this.memory = memory;
return this;
}
public Phone build() {
return new Phone(this);
}
}
}
- 测试
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.cpu("麒麟")
.screen("华为")
.mainBoard("华硕")
.build();
}
}