Java小白-设计模式
一、什么是设计模式
简单点说,设计模式(Design Pattern)就是前人踩坑总结出来的、能反复用的、解决常见软件设计问题的套路。它就是一套被验证过很多次的“万能方案”,有了它你写程序就不会瞎写,而是用一套聪明的、优雅的思路去组织代码,让程序更好写、更好维护、更容易扩展。
二、为啥要学设计模式?
因为做项目的时候,总是会碰到这些场景:有些对象只想要一个(单例 Singleton);有时想根据需求创建不同的对象(工厂 Factory);有两个模块接口对不上,需要接个“转接头”(适配器 Adapter);有时候需要让别人替你干活,还要做点额外事(代理 Proxy)
三、设计模式大致分几类?
分类 | 中文名 | 英文名 | 一句话定位 |
---|---|---|---|
创建型(5 种) | 单例 | Singleton | 全局只有一个实例 |
简单工厂* | Simple Factory* | 用一个工厂方法生产对象 | |
工厂方法 | Factory Method | 让子类决定创建哪个具体实例 | |
抽象工厂 | Abstract Factory | 创建“一族”相互依赖的对象 | |
建造者 | Builder | 按步骤组装复杂对象 | |
原型 | Prototype | 通过克隆而不是 new 来创建 | |
结构型(7 种) | 适配器 | Adapter | 把旧接口转换成客户端期望的新接口 |
桥接 | Bridge | 抽象与实现分离,两者可独立变化 | |
组合 | Composite | 把对象组合成树形结构表示“整体-部分” | |
装饰 | Decorator | 动态地给对象加功能,比继承灵活 | |
外观 | Facade | 对外统一高层接口,隐藏子系统复杂度 | |
享元 | Flyweight | 共享细粒度对象,节省内存 | |
代理 | Proxy | 用一个占位对象控制对真实对象的访问 | |
行为型(11 种) | 责任链 | Chain of Responsibility | 请求沿链传递,直到被处理 |
命令 | Command | 把请求封装成对象,实现参数化与撤销 | |
解释器 | Interpreter | 定义语言的文法并解释执行 | |
迭代器 | Iterator | 顺序访问聚合元素,不暴露其内部结构 | |
中介者 | Mediator | 对象间不直接通信,统一由中介转发 | |
备忘录 | Memento | 保存对象状态,可恢复 | |
观察者 | Observer | 一对多状态变化通知 | |
状态 | State | 状态改变时行为跟着改变 | |
策略 | Strategy | 封装算法族,可动态互换 | |
模板方法 | Template Method | 算法骨架固定,把步骤延迟到子类 | |
访问者 | Visitor | 不改变类结构即可扩展其操作 |
单例模式(Singleton Pattern)
单例模式的核心思想:自己管自己,全局唯一。保证一个类在整个程序中只有一个实例,并且提供一个全局访问点。
系统中只能有一个对象的时候使用,比如:线程池、配置管理器、日志对象、数据库连接池。
public class Singleton {private static volatile Singleton instance; // 加 volatile 保证可见性和防止指令重排private Singleton() {} // 私有构造public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) { // 双重检查instance = new Singleton();}}}return instance;}
}
工厂模式(Factory Pattern)
把对象的创建过程封装起来,把“new”操作交给工厂,客户端只需要告诉工程需要什么就行。
用处:当需要创建复杂对象时,不想把 new
散落到各处,想统一管理;创建对象的过程可能变化,但对外接口不变。
例子:简单工厂模式(一个工厂生产多种产品)
// 产品接口
interface Product {void show();
}// 具体产品A
class ProductA implements Product {public void show() {System.out.println("生产了产品A");}
}// 具体产品B
class ProductB implements Product {public void show() {System.out.println("生产了产品B");}
}// 工厂类
class SimpleFactory {public static Product createProduct(String type) {if ("A".equals(type)) {return new ProductA();} else if ("B".equals(type)) {return new ProductB();}throw new IllegalArgumentException("没有这个产品");}
}// 客户端
public class FactoryTest {public static void main(String[] args) {Product p1 = SimpleFactory.createProduct("A");p1.show();Product p2 = SimpleFactory.createProduct("B");p2.show();}
}
适配器模式(Adapter Pattern)
它把一个类的接口转换成客户希望的另一个接口,相当于“转接头”,使原本接口不兼容的两个类可以协同工作。
用处:老代码和新代码对不上;第三方库接口和自己接口对不上;不想改老代码,只想中间做个适配。
例子:手机充电头适配器
// 目标接口(客户期望的接口)
interface Target {void request();
}// 已有功能(不兼容的接口)
class Adaptee {public void specificRequest() {System.out.println("充电:220V 交流电");}
}// 适配器
class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}public void request() {System.out.println("使用适配器...");adaptee.specificRequest();}
}// 客户端
public class AdapterTest {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new Adapter(adaptee);target.request();}
}
代理模式(Proxy Pattern)
它为其他对象提供一种访问控制,代理对象在目标对象之前起到中介作用,可以在前后做一些额外操作(权限控制、延迟加载、记录日志等)。
用处:需要对目标对象做控制(加权限、加缓存);不想或者不能修改目标对象代码;远程代理(RMI)、虚拟代理(延迟加载)、安全代理(权限控制)等场景。
例子:静态代理
// 接口
interface Service {void operation();
}// 真实对象
class RealService implements Service {public void operation() {System.out.println("执行真实操作...");}
}// 代理对象
class ProxyService implements Service {private RealService realService;public ProxyService(RealService realService) {this.realService = realService;}public void operation() {System.out.println("开始代理,做一些额外操作...");realService.operation();System.out.println("代理结束...");}
}// 客户端
public class ProxyTest {public static void main(String[] args) {RealService realService = new RealService();ProxyService proxy = new ProxyService(realService);proxy.operation();}
}
这些模式就是最适合Java 学生先掌握的核心四个,理解了这几个,剩下的其他设计模式学起来也是举一反三。