一.单例模式

1.饿汉式



将构造器私有后 无法再new A的对象
而外面无法创建A对象了 想通过调用类方法来得到对象 而类方法只会返回类变量a
而静态只会执行一次 所以只会有一个对象
2.懒汉式



3.案例讲解

java
public class Principle {
private static Principle principle;
public String name;
private Principle(String name){
this.name=name;
}
public static Principle getPrinciple(){
if(principle==null){
principle=new Principle("王校长");
}
return principle;
}
public void announcement(String message){
System.out.println(name+"通知了"+message);
}
public void approvrDocument(String file){
System.out.println(name+"审判了"+file);
}
}
java
public class School {
public static void main(String[] args) {
Principle pr1=Principle.getPrinciple();
pr1.announcement("放假三天");
Principle pr2=Principle.getPrinciple();
pr2.approvrDocument("食堂整改文件");
if(pr2==pr1){
System.out.println("上述两个校长是一个人");
}else {
System.out.println("上述两个校长不是一个人");
}
}
}
二.工厂模式

- 抽象产品(Product)
-
写:接口 / 抽象类
-
内容:定义产品的通用方法(如 call ()、move ()、work ())
-
作用:规范所有产品
- 具体产品(ConcreteProduct)
-
写:实现抽象产品的普通类
-
内容:重写抽象方法,写真正业务逻辑
-
作用:真正干活的对象
- 抽象工厂(Factory)
-
写:接口 / 抽象类
-
内容:定义创建产品的方法(如 createPhone ())
-
作用:规范所有工厂
- 具体工厂(ConcreteFactory)
-
写:实现抽象工厂的普通类
-
内容:重写创建方法,new 对应产品并返回
-
作用:只负责创建一种产品
- 测试类(Client)
-
写:main 方法
-
内容:创建工厂 → 用工厂创建产品 → 调用产品方法
-
作用:使用模式,不直接 new 产品











- 解耦 :对象创建和使用分离,调用者无需知道对象创建细节(不用写
new IPhone()); - 复用:创建逻辑集中在工厂,避免重复代码;
- 易扩展:新增产品只需修改 / 新增工厂,不影响业务代码;
- 易维护:创建逻辑出问题时,只需改工厂类,不用改所有调用处。
三.代理模式

为目标对象(被代理者)提供一个 "代理对象",由代理对象控制对目标对象的访问 ,并可以在访问前后添加额外逻辑(比如日志、权限校验、事务),而目标对象只需专注于核心业务。
静态代理是代理模式的基础版本,特点是:代理类在编译期就已确定。
你(目标对象)想租房,但不想自己找房源、谈价格、签合同(额外逻辑),只专注于 "住房子"(核心业务);中介(代理对象)帮你完成所有额外操作,你只需通过中介就能租到房子,且中介可以在租房前后加自己的操作(比如收中介费、核验身份)。
静态代理的核心要素
- 共同接口:目标类和代理类实现同一个接口(定义统一的业务方法);
- 目标类:实现核心业务逻辑(比如租房);
- 代理类:持有目标类对象,重写接口方法,在调用目标方法前后添加额外逻辑。
1.抽象主题(Subject)
-
写:接口
-
内容:定义真实对象和代理都要实现的方法(如 sell ()、request ())
-
作用:统一访问入口
- 真实主题(RealSubject)
-
写:实现接口的普通类
-
内容:重写方法,写核心业务逻辑
-
作用:真正做事的对象
- 代理类(Proxy)
-
写:实现接口的普通类
-
内容:
-
持有真实主题对象(new RealSubject ())
-
重写方法:
-
前置增强(日志、权限、判断)
-
调用真实对象的方法
-
后置增强(记录、收尾)
-
-
-
作用:增强功能,不修改原类
- 测试类(Client)
-
写:main 方法
-
内容:创建代理对象 → 调用代理方法
-
作用:间接访问真实对象
java
// 租房接口:定义核心业务方法
public interface RentHouse {
// 核心业务:租房
void rent();
}
java
// 租客类:专注于核心业务(租房)
public class Tenant implements RentHouse {
@Override
public void rent() {
System.out.println("租客:我要租朝南、带阳台的房子!"); // 核心业务逻辑
}
}
java
// 中介类:代理租客租房,添加额外逻辑
public class RentProxy implements RentHouse {
// 持有目标对象(租客)的引用
private RentHouse tenant;
// 构造方法:传入目标对象
public RentProxy(RentHouse tenant) {
this.tenant = tenant;
}
@Override
public void rent() {
// 调用目标方法前:额外逻辑(前置处理)
beforeRent();
// 调用目标对象的核心业务方法
tenant.rent();
// 调用目标方法后:额外逻辑(后置处理)
afterRent();
}
// 前置额外逻辑:找房源、核验身份
private void beforeRent() {
System.out.println("中介:帮租客找符合要求的房源,核验租客身份!");
}
// 后置额外逻辑:签合同、收中介费
private void afterRent() {
System.out.println("中介:和租客签租房合同,收取中介费!");
}
}
java
public class ProxyDemo {
public static void main(String[] args) {
// 1. 创建目标对象(租客)
RentHouse tenant = new Tenant();
// 2. 创建代理对象(中介),传入目标对象
RentHouse proxy = new RentProxy(tenant);
// 3. 调用代理对象的方法(实际是中介帮租客完成租房)
proxy.rent();
}
}

优点
- 解耦:目标类只关注核心业务,额外逻辑(日志、权限)全部交给代理类,代码职责清晰;
- 易扩展:无需修改目标类代码,只需在代理类中添加 / 修改额外逻辑(符合 "开闭原则");
- 简单易用:编译期确定代理关系,代码结构清晰,新手易理解。
缺点
- 类数量膨胀 :每一个目标类都需要对应一个代理类(比如新增
Landlord房东类,就要新增LandlordProxy); - 维护成本高:如果接口新增方法,所有目标类和代理类都要同步修改;
- 灵活性低:代理关系编译期固定,无法动态切换代理逻辑。
