Java设计模式-入门篇

设计模式是软件开发中的"武功秘籍",它总结了前辈们在解决特定问题时积累的最佳实践。今天我们就用最通俗易懂的方式,来聊聊Java中那些常用的设计模式。

一、设计模式是什么?

想象你要装修房子:

  • 没有设计模式:每次装修都从零开始,容易犯错

  • 使用设计模式:有现成的装修方案模板,比如"客厅怎么装""卧室怎么布局"

设计模式就是软件开发的"装修模板",它帮我们:

  1. 解决常见问题

  2. 提高代码复用性

  3. 让代码更易维护

  4. 促进团队沟通

二、单例模式:独一无二的对象

场景:整个程序只需要一个对象,比如配置管理器、数据库连接池

public class AppConfig {
    // 1. 私有静态实例
    private static AppConfig instance;
    
    // 2. 私有构造方法
    private AppConfig() {}
    
    // 3. 全局访问点
    public static AppConfig getInstance() {
        if (instance == null) {
            instance = new AppConfig();
        }
        return instance;
    }
}

// 使用
AppConfig config = AppConfig.getInstance();

特点

  • 一个类只有一个实例

  • 自行创建这个实例

  • 向整个系统提供这个实例

典型应用

  • 配置管理器

  • 数据库连接池

  • 日志系统

演进历程

  1. 饿汉式(类加载时初始化)

  2. 懒汉式(首次使用时初始化)

  3. 双重检查锁定(解决线程安全问题)

  4. 静态内部类(利用类加载机制保证线程安全)

  5. 枚举实现(防止反射攻击)

注意事项

  • 多线程环境下需要加锁

  • 考虑使用枚举实现更安全的单例

三、工厂模式:对象的流水线

场景:创建对象的过程比较复杂,或者需要根据不同条件创建不同对象

3.1 简单工厂

public class AnimalFactory {
    public Animal createAnimal(String type) {
        if ("dog".equals(type)) {
            return new Dog();
        } else if ("cat".equals(type)) {
            return new Cat();
        }
        return null;
    }
}

// 使用
AnimalFactory factory = new AnimalFactory();
Animal dog = factory.createAnimal("dog");

3.2 工厂方法模式

public interface AnimalFactory {
    Animal createAnimal();
}

public class DogFactory implements AnimalFactory {
    public Animal createAnimal() {
        return new Dog();
    }
}

// 使用
AnimalFactory factory = new DogFactory();
Animal dog = factory.createAnimal();

优点

  • 将对象创建与使用分离

  • 方便扩展新的产品类型

  • 代码更清晰易维护

3.2 抽象工厂模式(Abstract Factory)

与工厂方法对比

  • 工厂方法:创建单一产品

  • 抽象工厂:创建产品族

// 抽象工厂接口
public interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

// 具体工厂
public class WindowsFactory implements GUIFactory {
    public Button createButton() { return new WindowsButton(); }
    public TextField createTextField() { return new WindowsTextField(); }
}

应用场景

  • 跨平台UI组件

  • 数据库访问抽象

  • 游戏角色装备系统

 

四、观察者模式:消息通知系统

场景:当一个对象状态改变时,需要自动通知其他对象

// 观察者接口
public interface Observer {
    void update(String message);
}

// 被观察者
public class NewsAgency {
    private List<Observer> observers = new ArrayList<>();
    
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
    
    public void notifyObservers(String news) {
        for (Observer observer : observers) {
            observer.update(news);
        }
    }
}

// 具体观察者
public class NewsChannel implements Observer {
    public void update(String news) {
        System.out.println("收到新闻:" + news);
    }
}

// 使用
NewsAgency agency = new NewsAgency();
agency.addObserver(new NewsChannel());
agency.notifyObservers("Java 17发布啦!");

现实类比

  • 微信公众号(被观察者)

  • 订阅用户(观察者)

  • 新文章发布(状态变化)

  • 推送通知(update调用)

五、策略模式:随时切换的算法

场景:需要在运行时选择不同的算法或行为

// 策略接口
public interface PaymentStrategy {
    void pay(int amount);
}

// 具体策略
public class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("信用卡支付:" + amount);
    }
}

public class AlipayPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("支付宝支付:" + amount);
    }
}

// 上下文
public class ShoppingCart {
    private PaymentStrategy strategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void checkout(int amount) {
        strategy.pay(amount);
    }
}

// 使用
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new AlipayPayment());
cart.checkout(100);

优点

  • 算法可以自由切换

  • 避免使用多重条件判断

  • 扩展新的策略很容易

六、装饰器模式:给对象穿衣服

场景:需要动态地给对象添加功能

// 基础接口
public interface Coffee {
    double getCost();
    String getDescription();
}

// 具体组件
public class SimpleCoffee implements Coffee {
    public double getCost() {
        return 10;
    }
    
    public String getDescription() {
        return "普通咖啡";
    }
}

// 装饰器基类
public abstract class CoffeeDecorator implements Coffee {
    protected final Coffee decoratedCoffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
    
    public double getCost() {
        return decoratedCoffee.getCost();
    }
    
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }
}

// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public double getCost() {
        return super.getCost() + 2;
    }
    
    public String getDescription() {
        return super.getDescription() + ",加牛奶";
    }
}

// 使用
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + " 价格:" + coffee.getCost());

输出

普通咖啡,加牛奶 价格:12.0

特点

  • 比继承更灵活

  • 可以动态添加/删除功能

  • 避免子类爆炸

设计要点

  1. 装饰器和被装饰对象实现相同接口

  2. 装饰器持有被装饰对象的引用

  3. 可以在运行时动态添加功能

与继承对比

特性继承装饰器模式
扩展方式静态编译时动态运行时
功能组合需要创建子类任意组合装饰器
类数量容易导致类爆炸按需创建装饰器

七、设计模式基础认知

7.1 设计模式起源与发展

设计模式的概念最早由建筑师Christopher Alexander提出,后由"四人帮"(GoF)在1994年出版的《设计模式:可复用面向对象软件的基础》一书中引入软件开发领域。该书系统性地总结了23种经典设计模式,这些模式至今仍是软件开发的基石。

7.2 设计模式的三大类别

创建型模式(5种)

作用:处理对象创建机制,增加系统灵活性

  • 单例模式

  • 工厂方法模式

  • 抽象工厂模式

  • 建造者模式

  • 原型模式

结构型模式(7种)

作用:关注类和对象的组合方式

  • 适配器模式

  • 装饰器模式

  • 代理模式

  • 外观模式

  • 桥接模式

  • 组合模式

  • 享元模式

行为型模式(11种)

作用:管理对象间的交互和职责分配

  • 策略模式

  • 观察者模式

  • 责任链模式

  • 命令模式

  • 迭代器模式

  • 状态模式

  • 模板方法模式

  • 访问者模式

  • 备忘录模式

  • 中介者模式

  • 解释器模式

7.3 设计模式的六大原则

  1. 开闭原则:对扩展开放,对修改关闭

  2. 单一职责:一个类只负责一个功能领域

  3. 里氏替换:子类必须能替换父类

  4. 依赖倒置:依赖抽象而非具体实现

  5. 接口隔离:使用多个专用接口

  6. 迪米特法则:最少知识原则

八、设计模式使用建议

  1. 不要过度设计:简单问题不需要复杂模式

  2. 理解优于套用:先理解问题,再选择模式

  3. 组合使用:实际项目往往是多个模式组合

  4. 保持灵活:根据项目演进调整设计

九、快速记忆口诀

模式名称一句话总结生活例子
单例模式保证只有一个实例公司CEO
工厂模式专门负责生产对象汽车工厂
观察者状态变化自动通知微信订阅
策略自由切换算法支付方式
装饰器动态添加功能给手机加壳

记住:设计模式不是银弹,而是工具箱里的工具。用对场景才是关键!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值