单例模式
-
单例模式(
Singleton
):一个类只有一个实例,且这个类能够自行创建这个实例的一种模式; -
单例模式特点:
- 一个单例类只能有一个单例模式;
- 该单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点;
-
单例模式优点:
- 单个类只有一个实例,减少内存开销;
- 可以避免对资源的多重占用;
- 单例模式设置全局访问点,可以优化和共享资源的访问;
-
单例模式缺点:
- 单例模式一般没有接口,扩展困难;
- 在并发测试中,单例模式不利于代码调试;
- 单例模式的功能代码通常写在一个类中,如果功能设计不合理,则很容易违背单一职责原则;
实现
- 懒汉模式:
public class LazySingleton{ private static volatile LazySingleton instance = null; private LazySingleton(){ } public static LazySingleton getInstance(){ if(instance == null) { //加局部锁,保证线程安全(双重校验锁) sychronized(LazySingleton.class){ if(instance == null) { instance = new LazySingleton(); } } } return instance; } }
- 饿汉模式:
public class HungrySingleton{ private static final HungrySingleton instance = new HungrySingleton(); private HungrySingleton(){ } //线程安全 public static HungrySingleton getInstance(){ return instance; } }
简单工厂模式
- 在日常开发中,凡是需要生成复杂对象的地方,都可以考虑使用工厂模式来代替;复杂对象直接在其他业务类中使用,会造成严重耦合,不利于后续维护;
- 简单工厂模式中:创建实例的方法通常称为静态方法,简单工厂模式又叫作静态工厂方法模式;
- 简单工厂模式优点:
- 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例;
- 客户端无须知道所创建具体产品的类名,只需要知道参数即可;
- 可以引入配置文件,在不修改客户端代码的情况下,更换和添加新的具体产品类;
- 简单工厂模式缺点:
- 工厂类单一,职责过重;
- 会增加类中个数,增加系统复杂度和理解难度;
- 系统扩展困难;
- 使用
static
方法,无法形成基于继承的等级结构;
- 简单工厂类:工厂类、抽象产品类、具体产品类;
//抽象产品
public interface Product{
void show();
}
//具体产品1
class ProductA implements Product{
public void show()
{
System.out.println("...");
}
}
//具体产品2
class ProductB implements Product{
public void show()
{
System.out.println("...");
}
}
//具体产品3
class ProductC implements Product{
public void show()
{
System.out.println("...");
}
}
//工厂类
class Factory{
public static Product makeProduct(int kind)
{
switch(kind){
case 1:
return new ProductA();
case 2:
return new ProductB();
case 3:
return new ProductC();
}
return null;
}
}
工厂方法模式
- 工厂方法模式类:抽象工厂,具体工厂,抽象产品,具体产品;
使用:
步骤1: 创建抽象工厂类,定义具体工厂的公共接口;
步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
步骤3: 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
//工厂模式实现
//抽象工厂
abstract class Factory{
public abstract Product makeProduct();
}
//抽象产品类
abstract class Product
{
public abstract void show();
}
//具体产品类1
class ProductA extends Product{
public void show()
{
System.out.println("...");
}
}
//具体产品类2
class ProductB extends Product{
public void show()
{
System.out.println("...");
}
}
//创建具体工厂类A
class FactoryA extends Factory{
public Product makeProduct(){
return new ProductA();
}
}
//创建具体工厂类B
class FactoryB extends Factory{
public Product makeProduct(){
return new ProductB();
}
}
//客户端调用
public class FactoryPattern{
public static void main(String[] args){
//要A产品
FactoryA mFactoryA = new FactoryA();
mFactoryA.makeProduct().show();
//要B产品
FactoryB mFactoryB = new FactoryB();
mFactoryB.makeProduct().show();
}
}
抽象工厂模式
- 普通工厂模式一次只能生产一类产品(考虑的是同等级产品),使用抽象工厂模式,可以一次实现多种模式:
- 抽象工厂模式组成类:抽象工厂,具体工厂,抽象产品,具体产品;(同普通工厂,不过抽象工厂包含的抽象产品更多)
//抽象工厂
interface AbstractFactory{
public Product1 newProduct1();
public Product2 newProduct2();
}
//具体工厂
class Factory1 implements AbstractFactory{
public Product1 newProduct1(){
System.out.println("11");
return new ConcreteProduct11();
}
public Product2 newProduct2(){
System.out.println("22");
return new ConcreteProduct21();
}
}
代理模式
-
代理模式:由于某些原因需要给某对象提供一个代理以控制对该对象的访问,访问对象不适合,不能直接引用目标对象,代理对象作为访问对象和目标对象之间点的中介;
-
代理模式优点:
- 代理模式可以在客户端和目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端和目标对象分离,在一定程度上降低了系统耦合度,增加了程序的可扩展性;
-
代理模式有静态代理,动态代理2种;
- 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译,在程序运行前代理类的 .class 文件就已经存在了。
- 动态:在程序运行时,运用反射机制动态创建而成;
-
代理模式主要类:抽象主题,真实主题,代理类
//代理模式实现:
//抽象主题
interface Subject{
void Request();
}
//真实主题
class RealSubject implements Subject{
public void Request()
{
System.out.println("...");
}
}
//代理
class Proxy implements Subject{
private RealSubject realSubject;
public void Request()
{
if(realSubject == null)
realSubject = new RealSubject();
preRequest(); //预处理
realSubject.Request();
postRequest();
}
public void preRequest()
{
System.out.println("访问真实主题之前的预处理");
}
public void postRequest()
{
System.out.println("访问真实主题之前的后处理");
}
}