单例模式
特点:
- 类构造器私有
- 持有自己类型的属性
- 对外提供获取实例的静态方法
懒汉模式:
线程不安全,延迟初始化
public class Singleton{
//懒汉模式
private static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
饿汉模式
线程安全,比较常用,但容易产生垃圾,因为一开始初始化
public class Singleton {
//饿汉模式
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getSingleton(){
return singleton;
}
}
双重锁模式
线程安全,延迟初始化。这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
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;
}
}
工厂模式
工厂模式(Factory Pattern)是Java最常用的设计模式之一。这种类型的设计模式属于创建模式,它提供了一种创建对象的最佳方式。
工厂模式分为简单工厂模式,工厂方法模式和抽象工厂模式。其主要功能都是帮助我们把对象的实例化部分抽取出来,目的是降低系统中代码的耦合度,并且增强了系统的扩展性。下面举例简单工厂模式:
创建一个Shape接口和实现Shape接口的实体类,下一步是定义工厂类ShapeFactory。
步骤1:
创建一个接口 Shape
public interface Shape {
void draw();
}
步骤2:
创建实现接口的实体类 Rectangle
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
创建实现接口的实体类 Square
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
创建实现接口的实体类 Circle
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
步骤3 创建一个工厂(ShapeFactory),生成基于给定信息的实体类的对象
public class ShapeFactory{
public Shape getShape(String shapetype){
if(shapetype==null)
return null;
if(shapetype.equalsIgnoreCase("Rectangle"))
return new Rectangle();
else if(shapetype.equalsIgnoreCase("Square"))
return new Square();
else if(shapetype.equalsIgnoreCase("Circle"))
return new Circle();
return null;
}
}
步骤4 使用这个工厂,通过传递类型信息来获取实体类的对象
public class FactoryPatternDemo {
public static void main(String[] args){
ShapeFactory shapeFactory = new ShapeFactory();
//获取Rectangle的对象
Shape shapeR = shapeFactory.getShape("Rectangle");
//调用Rectangle对象的draw()方法
shapeR.draw();
//获取Square的对象
Shape shapeS = shapeFactory.getShape("Square");
//调用Square对象的draw()方法
shapeS.draw();
//获取Circle的对象
Shape shapeC = shapeFactory.getShape("Circle");
//调用Circle对象的draw()方法
shapeC.draw();
}
}
步骤五 执行程序,输出结果
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Circle::draw() method.
优点:
- 一个调用者想创建对象,只需要知道其名称就可以了;
- 扩展性高,如果要增加一个产品,只需要扩展一个工厂类就可以;
- 屏蔽产品的具体实现,调用者只关心产品的接口
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖(这并不是什么好事儿)
本篇博客参考视频:https://www.bilibili.com/video/BV1ge411s7UY?t=6372&p=2
最近又看到了菜鸟驿站上写的,哦果然更详细更准确。附上链接:
https://www.runoob.com/design-pattern/singleton-pattern.html