牛刀小试之设计模式

发布于:2025-09-10 ⋅ 阅读:(13) ⋅ 点赞:(0)

牛刀小试设计模式

目录

设计模式简介

什么是设计模式

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中一些不断重复出现的问题,以及该问题的解决方案。

设计模式的核心价值

1. 提高代码质量
  • 可读性:使用标准化的模式,代码更容易理解
  • 可维护性:结构清晰,便于修改和扩展
  • 可复用性:模式化的代码更容易在不同项目中复用
2. 解决常见问题
  • 解耦:降低类之间的耦合度
  • 扩展:便于功能的扩展和修改
  • 复用:提高代码的复用性
3. 团队协作
  • 沟通:团队成员对设计模式有共同理解
  • 规范:统一的代码设计规范
  • 效率:减少重复思考和设计时间

设计模式的历史

时间 重要事件 影响
1977年 Christopher Alexander提出建筑模式概念 为软件设计模式奠定基础
1994年 Gang of Four (GoF) 发布《设计模式》 正式确立23种经典设计模式
2002年 Martin Fowler发布《企业应用架构模式》 扩展了企业级应用设计模式
2008年 微服务架构兴起 涌现出新的架构模式
2014年 响应式编程模式 适应现代异步编程需求

设计模式分类

按目的分类

1. 创建型模式(Creational Patterns)

目的:解决对象创建的问题

模式名称 英文名称 主要作用 使用频率
单例模式 Singleton 确保一个类只有一个实例 ⭐⭐⭐⭐⭐
工厂方法模式 Factory Method 创建对象而不指定具体类 ⭐⭐⭐⭐
抽象工厂模式 Abstract Factory 创建相关对象族 ⭐⭐⭐
建造者模式 Builder 分步构建复杂对象 ⭐⭐⭐
原型模式 Prototype 通过克隆创建对象 ⭐⭐
2. 结构型模式(Structural Patterns)

目的:解决类和对象的组合问题

模式名称 英文名称 主要作用 使用频率
适配器模式 Adapter 让不兼容的接口协同工作 ⭐⭐⭐⭐
装饰器模式 Decorator 动态添加功能 ⭐⭐⭐⭐
代理模式 Proxy 为对象提供代理控制访问 ⭐⭐⭐⭐
外观模式 Facade 为子系统提供统一接口 ⭐⭐⭐
桥接模式 Bridge 分离抽象和实现 ⭐⭐
组合模式 Composite 树形结构处理 ⭐⭐
享元模式 Flyweight 共享细粒度对象
3. 行为型模式(Behavioral Patterns)

目的:解决对象间的通信和职责分配问题

模式名称 英文名称 主要作用 使用频率
观察者模式 Observer 定义一对多依赖关系 ⭐⭐⭐⭐⭐
策略模式 Strategy 定义算法族,使它们可互换 ⭐⭐⭐⭐
命令模式 Command 将请求封装为对象 ⭐⭐⭐⭐
模板方法模式 Template Method 定义算法骨架 ⭐⭐⭐⭐
状态模式 State 改变对象行为 ⭐⭐⭐
责任链模式 Chain of Responsibility 避免请求发送者和接收者耦合 ⭐⭐⭐
迭代器模式 Iterator 顺序访问聚合对象 ⭐⭐⭐
中介者模式 Mediator 减少对象间直接交互 ⭐⭐
备忘录模式 Memento 保存和恢复对象状态 ⭐⭐
访问者模式 Visitor 在不改变类结构下定义新操作
解释器模式 Interpreter 定义语言语法

按范围分类

1. 类模式
  • 处理类与子类之间的关系
  • 通过继承建立关系
  • 编译时确定关系

典型模式

  • 模板方法模式
  • 工厂方法模式
  • 适配器模式(类适配器)
2. 对象模式
  • 处理对象间的关系
  • 通过组合建立关系
  • 运行时确定关系

典型模式

  • 单例模式
  • 观察者模式
  • 策略模式
  • 装饰器模式

设计模式使用场景

创建型模式使用场景

1. 单例模式

适用场景

  • 需要全局唯一实例的类
  • 资源管理器(数据库连接池、线程池)
  • 配置管理器
  • 日志记录器
// 线程安全的单例模式
public class DatabaseConnection {
    private static volatile DatabaseConnection instance;
  
    private DatabaseConnection() {}
  
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            synchronized (DatabaseConnection.class) {
                if (instance == null) {
                    instance = new DatabaseConnection();
                }
            }
        }
        return instance;
    }
}
2. 工厂方法模式

适用场景

  • 创建对象时不知道具体类型
  • 需要根据条件创建不同对象
  • 希望扩展产品类型
// 支付方式工厂
public interface PaymentFactory {
    Payment createPayment();
}

public class AlipayFactory implements PaymentFactory {
    @Override
    public Payment createPayment() {
        return new AlipayPayment();
    }
}

public class WechatPayFactory implements PaymentFactory {
    @Override
    public Payment createPayment() {
        return new WechatPayPayment();
    }
}
3. 建造者模式

适用场景

  • 构建复杂对象
  • 需要分步构建
  • 构建过程需要灵活配置
// 用户信息建造者
public class User {
    private String name;
    private String email;
    private int age;
    private String address;
  
    private User(Builder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.address = builder.address;
    }
  
    public static class Builder {
        private String name;
        private String email;
        private int age;
        private String address;
      
        public Builder name(String name) {
            this.name = name;
            return this;
        }
      
        public Builder email(String email) {
            this.email = email;
            return this;
        }
      
        public Builder age(int age) {
            this.age = age;
            return this;
        }
      
        public Builder address(String address) {
            this.address = address;
            return this;
        }
      
        public User build() {
            return new User(this);
        }
    }
}

结构型模式使用场景

1. 适配器模式

适用场景

  • 使用第三方库时接口不匹配
  • 系统升级时保持向后兼容
  • 集成不同厂商的组件
// 媒体播放器适配器
public interface MediaPlayer {
    void play(String audioType, String fileName);
}

public interface AdvancedMediaPlayer {
    void playVlc(String fileName);
    void playMp4(String fileName);
}

public class MediaAdapter implements MediaPlayer {
    AdvancedMediaPlayer advancedMusicPlayer;
  
    public MediaAdapter(String audioType) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer = new Mp4Player();
        }
    }
  
    @Override
    public void play(String audioType, String fileName) {
        if (audioType.equalsIgnoreCase("vlc")) {
            advancedMusicPlayer.playVlc(fileName);
        } else if (audioType.equalsIgnoreCase("mp4")) {
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}
2. 装饰器模式

适用场景

  • 需要动态添加功能
  • 不能使用继承时
  • 需要透明地扩展对象功能
// 咖啡装饰器
public abstract class Coffee {
    public abstract String getDescription();
    public abstract double cost();
}

public class SimpleCoffee extends Coffee {
    @Override
    public String getDescription() {
        return "Simple coffee";
    }
  
    @Override
    public double cost() {
        return 1.0;
    }
}

public abstract class CoffeeDecorator extends Coffee {
    protected Coffee coffee;
  
    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
  
    @Override
    public String getDescription() {
        return coffee.getDescription() + ", milk";
    }
  
    @Override
    public double cost() {
        return coffee.cost() + 0.5;
    }
}
3. 代理模式

适用场景

  • 需要控制对对象的访问
  • 延迟加载
  • 缓存代理
  • 权限控制
// 图片代理
public interface Image {
    void display();
}

public class RealImage implements Image {
    private String fileName;
  
    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk(fileName);
    }
  
    @Override
    public void display() {
        System.out.println("Displaying " + fileName);
    }
  
    private void loadFromDisk(String fileName) {
        System.out.println("Loading " + fileName);
    }
}

public class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;
  
    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }
  
    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }
}

行为型模式使用场景

1. 观察者模式

适用场景

  • 一对多依赖关系
  • 事件处理系统
  • 模型-视图架构
  • 发布-订阅系统
// 新闻发布订阅系统
public interface Observer {
    void update(String news);
}

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

public class NewsAgency implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String news;
  
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
  
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
  
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(news);
        }
    }
  
    public void setNews(String news) {
        this.news = news;
        notifyObservers();
    }
}

public class NewsChannel implements Observer {
    private String name;
  
    public NewsChannel(String name) {
        this.name = name;
    }
  
    @Override
    public void update(String news) {
        System.out.println(name + " received news: " + news);
    }
}
2. 策略模式

适用场景

  • 需要动态选择算法
  • 算法族需要互换
  • 避免使用多重条件判断
// 支付策略
public interface PaymentStrategy {
    void pay(double amount);
}

public class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    private String cvv;
  
    public CreditCardPayment(String cardNumber, String cvv) {
        this.cardNumber = cardNumber;
        this.cvv = cvv;
    }
  
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using Credit Card");
    }
}

public class PayPalPayment implements PaymentStrategy {
    private String email;
  
    public PayPalPayment(String email) {
        this.email = email;
    }
  
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using PayPal");
    }
}

public class PaymentContext {
    private PaymentStrategy strategy;
  
    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
  
    public void executePayment(double amount) {
        strategy.pay(amount);
    }
}
3. 命令模式

适用场景

  • 需要撤销/重做操作
  • 需要将请求排队
  • 需要支持日志和事务
// 遥控器命令
public interface Command {
    void execute();
    void undo();
}

public class Light {
    public void on() {
        System.out.println("Light is on");
    }
  
    public void off() {
        System.out.println("Light is off");
    }
}

public class LightOnCommand implements Command {
    private Light light;
  
    public LightOnCommand(Light light) {
        this.light = light;
    }
  
    @Override
    public void execute() {
        light.on();
    }
  
    @Override
    public void undo() {
        light.off();
    }
}

public class RemoteControl {
    private Command command;
  
    public void setCommand(Command command) {
        this.command = command;
    }
  
    public void pressButton() {
        command.execute();
    }
  
    public void pressUndo() {
        command.undo();
    }
}

设计模式重难点分析

创建型模式重难点

1. 单例模式

重难点

  • 线程安全:多线程环境下的实例创建
  • 序列化:防止反序列化创建新实例
  • 反射攻击:防止通过反射创建实例
  • 内存泄漏:静态实例的生命周期管理

解决方案

// 枚举单例(推荐)
public enum Singleton {
    INSTANCE;
  
    public void doSomething() {
        // 业务逻辑
    }
}

// 双重检查锁定
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;
    }
}
2. 工厂模式

重难点

  • 简单工厂 vs 工厂方法:选择合适的工厂模式
  • 抽象工厂的复杂性:管理多个产品族
  • 扩展性:添加新产品时的修改成本

解决方案

// 使用反射的通用工厂
public class GenericFactory<T> {
    private Map<String, Class<? extends T>> registeredClasses = new HashMap<>();
  
    public void registerClass(String type, Class<? extends T> clazz) {
        registeredClasses.put(type, clazz);
    }
  
    public T create(String type) {
        Class<? extends T> clazz = registeredClasses.get(type);
        if (clazz == null) {
            throw new IllegalArgumentException("Unknown type: " + type);
        }
        try {
            return clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Failed to create instance", e);
        }
    }
}

结构型模式重难点

1. 适配器模式

重难点

  • 类适配器 vs 对象适配器:选择合适的实现方式
  • 接口设计:如何设计合适的适配器接口
  • 性能影响:适配器可能带来的性能开销

解决方案

// 对象适配器(推荐)
public class ObjectAdapter implements Target {
    private Adaptee adaptee;
  
    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
  
    @Override
    public void request() {
        adaptee.specificRequest();
    }
}
2. 装饰器模式

重难点

  • 装饰器链:多个装饰器的组合使用
  • 顺序问题:装饰器的应用顺序
  • 性能考虑:装饰器链的性能影响

解决方案

// 装饰器链管理
public class DecoratorChain {
    private List<Decorator> decorators = new ArrayList<>();
  
    public void addDecorator(Decorator decorator) {
        decorators.add(decorator);
    }
  
    public Component build(Component component) {
        Component result = component;
        for (Decorator decorator : decorators) {
            result = decorator.decorate(result);
        }
        return result;
    }
}

行为型模式重难点

1. 观察者模式

重难点

  • 内存泄漏:观察者未正确移除
  • 通知顺序:多个观察者的通知顺序
  • 异常处理:观察者处理异常时的策略

解决方案

// 安全的观察者模式
public class SafeSubject implements Subject {
    private List<Observer> observers = new CopyOnWriteArrayList<>();
  
    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            try {
                observer.update();
            } catch (Exception e) {
                // 记录异常,不影响其他观察者
                System.err.println("Observer failed: " + e.getMessage());
            }
        }
    }
}
2. 策略模式

重难点

  • 策略选择:如何选择合适的策略
  • 策略切换:运行时策略切换的复杂性
  • 策略组合:多个策略的组合使用

解决方案

// 策略选择器
public class StrategySelector {
    private Map<String, Strategy> strategies = new HashMap<>();
  
    public void registerStrategy(String key, Strategy strategy) {
        strategies.put(key, strategy);
    }
  
    public Strategy selectStrategy(String key) {
        Strategy strategy = strategies.get(key);
        if (strategy == null) {
            throw new IllegalArgumentException("Unknown strategy: " + key);
        }
        return strategy;
    }
}

设计模式在实际项目中的应用

Spring框架中的设计模式

1. 单例模式
// Spring Bean默认单例
@Component
public class UserService {
    // Spring容器管理单例
}

// 配置单例
@Configuration
public class AppConfig {
    @Bean
    @Scope("singleton")
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}
2. 工厂模式
// Spring的BeanFactory
@Configuration
public class PaymentConfig {
    @Bean
    public PaymentFactory paymentFactory() {
        return new PaymentFactory();
    }
  
    @Bean
    public PaymentService paymentService(PaymentFactory factory) {
        return new PaymentService(factory);
    }
}
3. 代理模式
// Spring AOP代理
@Service
public class UserService {
  
    @Transactional
    public void saveUser(User user) {
        // 业务逻辑
    }
  
    @Cacheable("users")
    public User findById(Long id) {
        // 查询逻辑
    }
}
4. 观察者模式
// Spring事件机制
@Component
public class UserEventListener {
  
    @EventListener
    public void handleUserCreated(UserCreatedEvent event) {
        // 处理用户创建事件
    }
  
    @EventListener
    public void handleUserUpdated(UserUpdatedEvent event) {
        // 处理用户更新事件
    }
}

// 发布事件
@Service
public class UserService {
  
    @Autowired
    private ApplicationEventPublisher eventPublisher;
  
    public void createUser(User user) {
        // 创建用户逻辑
        eventPublisher.publishEvent(new UserCreatedEvent(user));
    }
}

微服务架构中的设计模式

1. 服务发现模式
// 服务注册
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

// 服务发现
@Service
public class OrderService {
  
    @Autowired
    private DiscoveryClient discoveryClient;
  
    public List<ServiceInstance> getUserServiceInstances() {
        return discoveryClient.getInstances("user-service");
    }
}
2. 熔断器模式
// Hystrix熔断器
@Service
public class UserService {
  
    @HystrixCommand(fallbackMethod = "getUserFallback")
    public User getUser(Long id) {
        // 调用远程服务
        return userClient.getUser(id);
    }
  
    public User getUserFallback(Long id) {
        return new User(id, "Default User");
    }
}
3. 网关模式
// Spring Cloud Gateway
@Configuration
public class GatewayConfig {
  
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("user-service", r -> r.path("/api/users/**")
                .uri("lb://user-service"))
            .route("order-service", r -> r.path("/api/orders/**")
                .uri("lb://order-service"))
            .build();
    }
}

数据库操作中的设计模式

1. 仓储模式
// 通用仓储接口
public interface Repository<T, ID> {
    T save(T entity);
    Optional<T> findById(ID id);
    List<T> findAll();
    void deleteById(ID id);
}

// 用户仓储
@Repository
public class UserRepository implements Repository<User, Long> {
  
    @Autowired
    private JdbcTemplate jdbcTemplate;
  
    @Override
    public User save(User user) {
        // 保存用户逻辑
        return user;
    }
  
    @Override
    public Optional<User> findById(Long id) {
        // 查询用户逻辑
        return Optional.empty();
    }
}
2. 工作单元模式
// 工作单元接口
public interface UnitOfWork {
    void registerNew(Object entity);
    void registerDirty(Object entity);
    void registerDeleted(Object entity);
    void commit();
    void rollback();
}

// 工作单元实现
@Component
public class JpaUnitOfWork implements UnitOfWork {
  
    @Autowired
    private EntityManager entityManager;
  
    private List<Object> newEntities = new ArrayList<>();
    private List<Object> dirtyEntities = new ArrayList<>();
    private List<Object> deletedEntities = new ArrayList<>();
  
    @Override
    public void registerNew(Object entity) {
        newEntities.add(entity);
    }
  
    @Override
    public void commit() {
        try {
            for (Object entity : newEntities) {
                entityManager.persist(entity);
            }
            for (Object entity : dirtyEntities) {
                entityManager.merge(entity);
            }
            for (Object entity : deletedEntities) {
                entityManager.remove(entity);
            }
            entityManager.getTransaction().commit();
        } catch (Exception e) {
            entityManager.getTransaction().rollback();
            throw e;
        }
    }
}

缓存设计中的设计模式

1. 装饰器模式
// 缓存装饰器
public class CachedUserService implements UserService {
  
    private final UserService userService;
    private final CacheManager cacheManager;
  
    public CachedUserService(UserService userService, CacheManager cacheManager) {
        this.userService = userService;
        this.cacheManager = cacheManager;
    }
  
    @Override
    public User findById(Long id) {
        Cache cache = cacheManager.getCache("users");
        User user = cache.get(id, User.class);
      
        if (user == null) {
            user = userService.findById(id);
            cache.put(id, user);
        }
      
        return user;
    }
}
2. 策略模式
// 缓存策略
public interface CacheStrategy {
    void put(String key, Object value);
    Object get(String key);
    void evict(String key);
}

// LRU缓存策略
public class LRUCacheStrategy implements CacheStrategy {
    private final Map<String, Object> cache = new LinkedHashMap<String, Object>(16, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) {
            return size() > 1000;
        }
    };
  
    @Override
    public synchronized void put(String key, Object value) {
        cache.put(key, value);
    }
  
    @Override
    public synchronized Object get(String key) {
        return cache.get(key);
    }
}

设计模式最佳实践

1. 模式选择原则

何时使用设计模式
  • 问题重复出现:相同问题多次遇到
  • 代码结构复杂:需要更好的组织结构
  • 团队协作:需要统一的代码规范
  • 系统扩展:需要支持未来扩展
何时不使用设计模式
  • 过度设计:简单问题不需要复杂模式
  • 性能敏感:模式可能带来性能开销
  • 团队不熟悉:团队对模式理解不够
  • 项目时间紧张:没有足够时间设计

2. 模式组合使用

常见模式组合
// 工厂 + 单例 + 策略
public class PaymentProcessor {
    private static final PaymentProcessor INSTANCE = new PaymentProcessor();
    private final Map<String, PaymentStrategy> strategies = new HashMap<>();
  
    private PaymentProcessor() {
        // 注册策略
        strategies.put("credit", new CreditCardStrategy());
        strategies.put("paypal", new PayPalStrategy());
    }
  
    public static PaymentProcessor getInstance() {
        return INSTANCE;
    }
  
    public void processPayment(String type, double amount) {
        PaymentStrategy strategy = strategies.get(type);
        if (strategy != null) {
            strategy.pay(amount);
        } else {
            throw new IllegalArgumentException("Unknown payment type: " + type);
        }
    }
}

3. 反模式识别

常见反模式
  • God Object:一个类承担过多职责
  • Spaghetti Code:代码结构混乱
  • Copy-Paste Programming:重复代码过多
  • Golden Hammer:过度使用某个模式
解决方案
// 反模式:God Object
public class UserManager {
    public void createUser() { /* ... */ }
    public void updateUser() { /* ... */ }
    public void deleteUser() { /* ... */ }
    public void sendEmail() { /* ... */ }
    public void logActivity() { /* ... */ }
    public void generateReport() { /* ... */ }
}

// 改进:职责分离
public class UserService {
    public void createUser() { /* ... */ }
    public void updateUser() { /* ... */ }
    public void deleteUser() { /* ... */ }
}

public class EmailService {
    public void sendEmail() { /* ... */ }
}

public class LoggingService {
    public void logActivity() { /* ... */ }
}

public class ReportService {
    public void generateReport() { /* ... */ }
}

4. 性能考虑

模式性能影响
模式 性能影响 建议
单例模式 推荐使用
工厂模式 推荐使用
装饰器模式 注意装饰器链长度
代理模式 考虑动态代理开销
观察者模式 注意观察者数量
策略模式 推荐使用
性能优化建议
// 对象池模式
public class ObjectPool<T> {
    private final Queue<T> pool = new ConcurrentLinkedQueue<>();
    private final Supplier<T> factory;
    private final int maxSize;
  
    public ObjectPool(Supplier<T> factory, int maxSize) {
        this.factory = factory;
        this.maxSize = maxSize;
    }
  
    public T acquire() {
        T object = pool.poll();
        if (object == null) {
            object = factory.get();
        }
        return object;
    }
  
    public void release(T object) {
        if (pool.size() < maxSize) {
            pool.offer(object);
        }
    }
}

总结

设计模式的核心价值

  1. 提高代码质量:使代码更加清晰、可维护、可扩展
  2. 解决常见问题:提供经过验证的解决方案
  3. 促进团队协作:建立统一的代码设计规范
  4. 降低学习成本:新团队成员更容易理解代码

学习建议

  1. 循序渐进:从简单模式开始,逐步学习复杂模式
  2. 实践为主:通过实际项目应用模式
  3. 理解原理:不仅要知道如何使用,更要理解为什么
  4. 避免过度使用:根据实际需要选择合适的模式

未来趋势

  1. 函数式编程模式:适应现代编程范式
  2. 响应式编程模式:处理异步和流式数据
  3. 微服务架构模式:支持分布式系统设计
  4. 云原生模式:适应云计算环境

设计模式是软件工程中的重要工具,掌握它们能够显著提高代码质量和开发效率。但记住,模式是工具,不是目的,应该根据实际需要合理使用。


网站公告

今日签到

点亮在社区的每一天
去签到