
在 Java 编程中,设计模式是解决常见问题的优秀方案。本文将深入剖析单例模式、工厂模式和代理模式。
一、单例模式
单例模式确保一个类只有一个实例。
1. 饿汉式
程序启动时就进行单例对象的初始化,无论是否被使用。线程安全但可能浪费资源。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}
public class Test {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton1 == singleton2);
}
}

2. 懒汉式
延迟加载,单例对象在首次访问时才初始化,节省了资源。
public class Singleton2 {
private static Singleton2 instance;
private Singleton2() {}
public static Singleton2 getSingleton() {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
二、工厂模式
工厂模式定义一个创建对象的接口,使创建对象的过程和使用对象的过程分离。
- 创建工厂接口(抽象工程)
public interface UserFactory {
User createUser(String name, int age);
}
- 实现具体工厂
public class AdminFactory implements UserFactory {
@Override
public User createUser(String name, int age) {
return new AdminUser(name, age);
}
}
public class NormalFactory implements UserFactory {
@Override
public User createUser(String name, int age) {
return new NormalUser(name, age);
}
}
- 使用方式
public class Test {
public static void main(String[] args) {
// 管理员
UserFactory adminFactory = new AdminFactory();
User admin = adminFactory.createUser("baby", 10);
// 用户
UserFactory normalFactory = new NormalFactory();
User normal1 = normalFactory.createUser("lisy", 12);
User normal2 = normalFactory.createUser("long", 14);
}
}
在工厂方法模式中,每种用户类型都有自己的工厂类。要添加新的用户类型,只需创建新的工厂类,无需修改现有代码。代码不会重复,创建对象的过程封装到了工厂当中更加解耦。
三、代理模式
一个类代表另一个类的功能,通过代理对象来控制实际对象的访问,相当于中介。
- User 类
public abstract class User {
protected String name;
protected int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public abstract void menu();
}
- NormalUser 和 AdminUser 类的结构如下
public class AdminUser extends User {
public AdminUser(String name, int age) {
super(name, age);
}
@Override
public void menu() {
System.out.println("管理员菜单");
}
public void addBook(String bookName) {
System.out.println("普通用户" + name + "借阅了" + bookName);
}
}
public class NormalUser extends User {
public NormalUser(String name, int age) {
super(name, age);
}
@Override
public void menu() {
System.out.println("普通用户的菜单");
}
public void borrowBook(String bookName) {
System.out.println("普通用户" + name + "借阅了" + bookName);
}
}
- 代理类结构
在该代理类中对 borrowBook、returnBook 方法提供了代理 ProxyUser 为不同类型的 User 提供代理。
public class ProxyUser {
private User realUser;
public ProxyUser(User user) {
this.realUser = user;
}
public void menu() {
this.realUser.menu();
}
public void borrowBook(String bookName) {
System.out.println("检查用户权限");
if (this.realUser instanceof NormalUser) {
((NormalUser) this.realUser).borrowBook(bookName);
} else {
System.out.println("没有权限借阅");
}
}
public void addBook(String bookName) {
System.out.println("检查用户权限");
if (this.realUser instanceof AdminUser) {
((AdminUser) this.realUser).addBook(bookName);
} else {
System.out.println("没有权限上架");
}
}
}
public static void main(String[] args) {
UserFactory adminFactory = new AdminFactory();
User admin = adminFactory.createUser("baby", 10);
UserFactory normalFactory = new NormalFactory();
User normal1 = normalFactory.createUser("lisy", 12);
// 代理模式
ProxyUser proxyAdminUser = new ProxyUser(admin);
proxyAdminUser.borrowBook("图书 1");
ProxyUser proxyNormalUser = new ProxyUser(normal1);
proxyNormalUser.addBook("图书 1");
proxyNormalUser.borrowBook("图书 1");
proxyNormalUser.borrowBook("图书 2");
}

总结
设计模式不是银弹,而是解决特定问题的优秀思路。在实际开发中,我们要根据具体场景选择合适的设计模式,让代码更加优雅、可维护。

