1.工厂模式
工厂模式可以细分为三种:1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式
1.简单工厂模式
- 核心思想:创建一个简单的工厂类,包含一个静态方法或者实例方法,根据传入的参数来决定创建并返回哪一种产品对象。
- 不满足开闭原则:当想要增加一个新的产品时,需要修改工厂类中的方法
- 适用场景:
- 产品种类相对固定,不太可能频繁增加。
- 创建逻辑相对简单。
- 代码示例
// 1. 产品接口
interface Product {
void operation();
}
// 2. 具体产品A
class ConcreteProductA implements Product {
@Override
public void operation() { System.out.println("Product A operation"); }
}
// 3. 具体产品B
class ConcreteProductB implements Product {
@Override
public void operation() { System.out.println("Product B operation"); }
}
// 4. 简单工厂
class SimpleFactory {
public static Product createProduct(String type) {
switch (type) {
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new IllegalArgumentException("Unknown product type");
}
}
}
// 5. 客户端使用
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.operation(); // Output: Product A operation
Product productB = SimpleFactory.createProduct("B");
productB.operation(); // Output: Product B operation
}
}
2.工厂方法模式
- 核心思想:定义一个用于创建对象的工厂接口,让它的子类来实现具体的类。
- 符合开闭原则:添加新的产品时,只需要添加新的具体产品类和具体的工厂类。不用修改现有的工厂。
- 单一职责原则:每个具体工厂只负责创建一种具体的产品。
- 适用场景:
- 无法预知需要创建哪种具体对象(依赖运行时条件)。
- 系统需要独立于其产品的创建、组合和表示。
- 需要提供产品的类库,并希望暴露其接口而不是实现。
- 希望将产品的创建过程委托给子类。
- 代码示例:
// 1. 产品接口
interface Product {
void operation();
}
// 2. 具体产品A
class ConcreteProductA implements Product {
@Override
public void operation() { System.out.println("Product A operation"); }
}
// 3. 具体产品B
class ConcreteProductB implements Product {
@Override
public void operation() { System.out.println("Product B operation"); }
}
// 4. 工厂接口
interface Factory {
Product createProduct();
}
// 5. 具体工厂A (生产产品A)
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
// 6. 具体工厂B (生产产品B)
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 7. 客户端使用
public class Client {
public static void main(String[] args) {
// 客户端决定使用哪个工厂(通常在配置中决定)
Factory factory = new ConcreteFactoryA(); // 假设配置了工厂A
Product product = factory.createProduct();
product.operation(); // Output: Product A operation
// 切换工厂只需改变factory的实例化
factory = new ConcreteFactoryB();
product = factory.createProduct();
product.operation(); // Output: Product B operation
}
}
3.抽象工厂模式
- 核心思想:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。它强调的是 产品族 的概念。
- 对产品族符合开闭原则:增加一个新的产品族只需要新增具体产品类和具体工厂类。
- 对某一类产品来说不满住开闭原则:新增某一类参评需要修改工厂接口和产品接口。
- 适用场景:
- 系统需要创建一系列相关的产品对象(属于同一个产品族)。
- 系统需要独立于其产品的创建、组合和表示。
- 系统需要配置多个产品族中的一个来使用。
- 需要强调产品之间的约束关系(比如必须是同一风格)。
- 代码示例:
// 1. 抽象产品: Button
interface Button {
void render();
}
// 2. 抽象产品: Checkbox
interface Checkbox {
void check();
}
// 3. 具体产品: Windows Button
class WindowsButton implements Button {
@Override
public void render() { System.out.println("Rendering a Windows button"); }
}
// 4. 具体产品: Windows Checkbox
class WindowsCheckbox implements Checkbox {
@Override
public void check() { System.out.println("Checking a Windows checkbox"); }
}
// 5. 具体产品: Mac Button
class MacButton implements Button {
@Override
public void render() { System.out.println("Rendering a Mac button"); }
}
// 6. 具体产品: Mac Checkbox
class MacCheckbox implements Checkbox {
@Override
public void check() { System.out.println("Checking a Mac checkbox"); }
}
// 7. 抽象工厂
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 8. 具体工厂: Windows 工厂 (生产Windows族产品)
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// 9. 具体工厂: Mac 工厂 (生产Mac族产品)
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// 10. 客户端使用
public class Application {
private Button button;
private Checkbox checkbox;
public Application(GUIFactory factory) {
// 使用同一个工厂创建相互关联的产品(保证是同一族)
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void paint() {
button.render();
checkbox.check();
}
public static void main(String[] args) {
// 配置使用哪个产品族 (通常在运行时根据配置决定)
GUIFactory factory;
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
factory = new WindowsFactory();
} else if (os.contains("mac")) {
factory = new MacFactory();
} else {
throw new UnsupportedOperationException("OS not supported");
}
Application app = new Application(factory);
app.paint();
// 如果配置WindowsFactory: Output: Rendering a Windows button / Checking a Windows checkbox
// 如果配置MacFactory: Output: Rendering a Mac button / Checking a Mac checkbox
}
}
2.单例模式
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {} // 私有构造
public static Singleton getInstance() {
return INSTANCE;
}
}
特点:
- 类加载时就初始化
- 实现简单
2.懒汉式(双重检查锁)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) { // 加锁
if (instance == null) { // 第二次检查
instance = new Singleton(); // 安全创建
}
}
}
return instance;
}
}
- 特点:
- 首次调用时创建
- 使用volatile防止指令重排
3.静态内部类
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
- 特点:
- 延迟初始化(Holder类首次加载时创建)
- 无锁机制,性能最优
- 天然线程安全(类加载机制保证)
3.适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它充当两个不兼容接口之间的桥梁,使原本因接口不兼容而无法一起工作的类能够协同工作。
- 核心思想:
- 接口转换:将一个类的接口转换成客户期望的另一个接口
- 兼容适配:解决接口不匹配问题
- 复用旧代码:使已有类在新系统中复用而无需修改
- 透明转换:客户端无需了解适配细节
- 结构:
- 实现方式
- 类适配器(继承)
// 目标接口(客户端期望的接口)
interface Target {
void request();
}
// 需要适配的类(已有但接口不兼容的类)
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee's specific request");
}
}
// 适配器(通过继承实现)
class ClassAdapter extends Adaptee implements Target {
@Override
public void request() {
// 转换调用
specificRequest();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Target target = new ClassAdapter();
target.request(); // 输出: Adaptee's specific request
}
}
- 对象适配器
// 目标接口(同上)
interface Target {
void request();
}
// 需要适配的类(同上)
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee's specific request");
}
}
// 适配器(通过组合实现)
class ObjectAdapter implements Target {
private Adaptee adaptee;
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
// 转换调用
adaptee.specificRequest();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new ObjectAdapter(adaptee);
target.request(); // 输出: Adaptee's specific request
}
}
- 一个例子
// 统一打印接口
interface Printer {
void print(String text);
}
// 旧式点阵打印机
class DotMatrixPrinter {
void printDotMatrix(String text) {
System.out.println("Dot Matrix: " + text);
}
}
// 适配器
class PrinterAdapter implements Printer {
private DotMatrixPrinter printer;
public PrinterAdapter(DotMatrixPrinter printer) {
this.printer = printer;
}
@Override
public void print(String text) {
printer.printDotMatrix(text);
}
}
4.观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,定义对象间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖它的对象都会得到通知并自动更新。
- 核心思想
- 解耦:将观察者与被观察者解耦
- 动态订阅:运行时动态添加/移除观察者
- 自动通知:状态变化时自动通知所有订阅者
- 广播通信:一对多的消息传递机制
- 代码示例
// 1. 主题接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
// 2. 观察者接口
interface Observer {
void update(String message);
}
// 3. 具体主题(被观察者)
class NewsPublisher implements Subject {
private List<Observer> observers = new ArrayList<>();
private String latestNews;
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(latestNews);
}
}
public void publishNews(String news) {
this.latestNews = news;
notifyObservers(); // 状态变化时通知所有观察者
}
}
// 4. 具体观察者
class EmailSubscriber implements Observer {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
@Override
public void update(String news) {
System.out.println("Sending email to " + email + ": " + news);
}
}
class MobileApp implements Observer {
private String deviceId;
public MobileApp(String deviceId) {
this.deviceId = deviceId;
}
@Override
public void update(String news) {
System.out.println("Push notification to " + deviceId + ": " + news);
}
}
// 5. 客户端使用
public class Client {
public static void main(String[] args) {
NewsPublisher publisher = new NewsPublisher();
Observer emailUser = new EmailSubscriber("user@example.com");
Observer appUser = new MobileApp("DEV-12345");
// 订阅
publisher.attach(emailUser);
publisher.attach(appUser);
// 发布新闻(自动通知所有订阅者)
publisher.publishNews("Breaking: New product launched!");
// 取消订阅
publisher.detach(appUser);
publisher.publishNews("Update: Special discount available!");
}
}