- 创建型模式:单例模式、工厂模式、原型模式
- 结构型模式:代理模式、装饰器模式
- 行为型模式:模板方法模式、责任链模式、观察者模式
- J2EE模式:MVC模式
单例模式
- 单例类只能有一个实例
- 单例类必须自己创建自己的唯一实例
- 单例类必须给所有其他对象提供这一实例
创建一个Singleton类
// SingleObject.java
public class SingleObject {
// 创建 SingleObejct 的一个对象
private static SingleObject instance = new SingleObject();
// 让构造函数为 private,这样该类就不会被实例化
private SingleObject(){}
// 获取唯一可用的对象
public static SingleObject getInstance() {
return instance;
}
public void showMessage() {
System.out.println("Hello Singleton!");
}
}
从Singleton类获取唯一对象
// SingletonPatternDemo.java
public class SingletonPatternDemo {
public static void main(String[] args) {
// 不合法的构造函数,编译时报错:构造函数SingleObject()是不可见的
// SingleObject object = new SingleObject();
// 获取唯一可用的对象
SingleObject object1 = SingleObject.getInstance();
SingleObject object2 = SingleObject.getInstance();
System.out.println(object1); // 地址一致,为同一个对象
System.out.println(object2); // 地址一致,为同一个对象
}
}
1. 懒汉式,线程安全(get方法加synchronized)
- 优点:第一次调用才进行初始化,避免内存浪费。
- 缺点:必须加锁synchronized才能保证单例,但加锁会影响效率。
public class Singleton1 {
private static Singleton1 instance;
private Singleton1() {}
public static synchronized Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}
2. 饿汉式
- 优点:没有加锁,执行效率会提高
- 缺点:类加载时就初始化,浪费内存。容易产生垃圾对象。
public class Singleton2 {
private static Singleton2 instance = new Singleton2();
private Singleton2() {}
public static Singleton2 getInstance() {
return instance;
}
}
3. 双检锁/双重校验锁(DCL,double-checked locking)
- 优点:多线程安全,并且保持高性能
- 缺点:实现较复杂
public class Singleton3 {
private static Singleton3 instance;
private Singleton3(){}
public static Singleton3 getInstance() {
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
工厂模式
- 优点:没有加锁,执行效率会提高
- 缺点:类加载时就初始化,浪费内存。容易产生垃圾对象。
public class Singleton2 {
private static Singleton2 instance = new Singleton2();
private Singleton2() {}
public static Singleton2 getInstance() {
return instance;
}
}
3. 双检锁/双重校验锁(DCL,double-checked locking)
- 优点:多线程安全,并且保持高性能
- 缺点:实现较复杂
public class Singleton3 {
private static Singleton3 instance;
private Singleton3(){}
public static Singleton3 getInstance() {
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
工厂模式
建立一个工厂类,对实现了同一接口的一些类进行实例的创建
- 优点:提供专门的工厂类用于创建对象。调用者只关心产品的接口,不需要了解具体的实现。
- 缺点:每增加一个产品都要增加一个具体类和对象实现工厂,系统复杂度比较高。增加了具体类的依赖。
抽象类实现
// 抽象类--咖啡
public abstract class Coffee {
public abstract String getName();
}
// 美式咖啡
public class Americano extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
// 卡布奇诺
public class Cappuccino extends Coffee {
@Override
public String getName() {
return "卡布奇诺";
}
}
接口实现
public interface Fruit{
public void eat(); //吃水果
}
// 苹果类
class Apple implements Fruit{
public void eat() {
System.out.println("吃苹果");
}
}
// 香蕉类
class Banana implements Fruit{
public void eat(){
System.out.println("吃香蕉");
}
}
// 测试调用
public class Factory{
public static void main(String[] args) {
Fruit fruit = new Apple();
fruit.eat(); // 吃苹果
}
}
代理模式
public interface Fruit{
public void eat(); //吃水果
}
// 苹果类
class Apple implements Fruit{
public void eat() {
System.out.println("吃苹果");
}
}
// 香蕉类
class Banana implements Fruit{
public void eat(){
System.out.println("吃香蕉");
}
}
// 测试调用
public class Factory{
public static void main(String[] args) {
Fruit fruit = new Apple();
fruit.eat(); // 吃苹果
}
}
代理模式
使用代理对象来代替真实对象,在不修改原目标对象的前提下,提供源对象的功能,同时还具备扩展目标对象的功能特性。
静态代理
静态代理实现步骤:
- 定义一个借口及其实现类
- 创建一个代理类同样实现这个接口
- 将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法
// 1. 定义发送资料接口
public interface MaterialService {
String send(String message);
}
// 2. 定义发送资料接口实现类(被代理对象)
public class MaterialServiceImpl implements MaterialService {
@Override
public String send(String message) {
System.out.println("send message:" + message);
return message;
}
}
// 3. 定义代理类并同样实现发送资料接口(代理对象)
public class MaterialProxy implements MaterialService {
private final MaterialServiceImpl materialService;
public MaterialProxy(MaterialServiceImpl materialService) {
this.materialService = materialService;
}
@Override
public String send(String message) {
// 调用方法之前,添加自己的操作
System.out.println("调用方法前,自己添加了操作");
materialService.send(message);
// 调用方法之后,添加自己的操作
System.out.println("调用方法后,自己添加了操作");
return message;
}
}



