|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// 【文件说明】HwNoopSearchRebuildService.cs - 空搜索重建服务
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// 这是一个"空对象"(Null Object)模式的实现,什么都不做。
|
|
|
|
|
|
//
|
|
|
|
|
|
// 【什么是空对象模式?】
|
|
|
|
|
|
// 空对象模式是一种设计模式:
|
|
|
|
|
|
// - 提供一个"什么都不做"的实现
|
|
|
|
|
|
// - 避免返回 null,减少空指针异常
|
|
|
|
|
|
// - 提供默认行为,简化调用方代码
|
|
|
|
|
|
//
|
|
|
|
|
|
// 【使用场景】
|
|
|
|
|
|
// 1. 测试环境:不需要真正重建索引
|
|
|
|
|
|
// 2. 配置禁用:搜索功能关闭时,使用空实现
|
|
|
|
|
|
// 3. 开发阶段:索引功能还未完成,先用空实现占位
|
|
|
|
|
|
//
|
|
|
|
|
|
// 【与 Java Spring Boot 的对比】
|
|
|
|
|
|
// Java 可以用 @Profile 或 @ConditionalOnProperty 实现:
|
|
|
|
|
|
// @Profile("test")
|
|
|
|
|
|
// @Service
|
|
|
|
|
|
// public class NoopSearchRebuildService implements IHwSearchRebuildService {
|
|
|
|
|
|
// @Override
|
|
|
|
|
|
// public void rebuildAllAsync() { }
|
|
|
|
|
|
// }
|
|
|
|
|
|
//
|
|
|
|
|
|
// C# 通过 DI 注册不同的实现,效果类似。
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
namespace Admin.NET.Plugin.HwPortal;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 空搜索重建服务。
|
|
|
|
|
|
/// <para>
|
|
|
|
|
|
/// 【设计模式 - 空对象模式】
|
|
|
|
|
|
/// 这个类实现了 IHwSearchRebuildService 接口,但方法体为空。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 为什么需要空实现?
|
|
|
|
|
|
/// 1. 避免空指针:调用方不需要判断 null
|
|
|
|
|
|
/// 2. 默认行为:未配置搜索功能时,使用空实现
|
|
|
|
|
|
/// 3. 测试方便:测试环境不需要真正重建索引
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 对比传统方式:
|
|
|
|
|
|
/// 传统方式需要判断 null:
|
|
|
|
|
|
/// if (_rebuildService != null) {
|
|
|
|
|
|
/// await _rebuildService.RebuildAllAsync();
|
|
|
|
|
|
/// }
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 空对象模式可以直接调用:
|
|
|
|
|
|
/// await _rebuildService.RebuildAllAsync(); // 如果是空实现,什么都不做
|
|
|
|
|
|
/// </para>
|
|
|
|
|
|
/// <para>
|
|
|
|
|
|
/// 【C# 语法知识点 - sealed 密封类】
|
|
|
|
|
|
/// sealed 表示不能被继承。空对象类通常不需要继承。
|
|
|
|
|
|
/// </para>
|
|
|
|
|
|
/// <para>
|
|
|
|
|
|
/// 【C# 语法知识点 - ITransient 瞬态服务】
|
|
|
|
|
|
/// ITransient 表示每次请求都创建新实例。
|
|
|
|
|
|
/// 空对象类没有状态,也可以用 ISingleton(单例)节省内存。
|
|
|
|
|
|
/// </para>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public sealed class HwNoopSearchRebuildService : IHwSearchRebuildService, ITransient
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 重建所有搜索索引(空实现)。
|
|
|
|
|
|
/// <para>
|
|
|
|
|
|
/// 【C# 语法知识点 - Task.CompletedTask】
|
|
|
|
|
|
/// Task.CompletedTask 是一个已完成的 Task 实例。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 为什么返回 CompletedTask?
|
|
|
|
|
|
/// 1. 方法签名要求返回 Task
|
|
|
|
|
|
/// 2. 空实现不需要异步操作
|
|
|
|
|
|
/// 3. 返回已完成的 Task,调用方 await 会立即返回
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 对比 Java:
|
|
|
|
|
|
/// Java 返回 CompletableFuture.completedFuture(null):
|
|
|
|
|
|
/// return CompletableFuture.completedFuture(null);
|
|
|
|
|
|
///
|
|
|
|
|
|
/// C# 的 Task.CompletedTask 更简洁。
|
|
|
|
|
|
///
|
|
|
|
|
|
/// 【性能说明】
|
|
|
|
|
|
/// Task.CompletedTask 是单例,不会创建新对象。
|
|
|
|
|
|
/// 比 Task.Run(() => { }) 更高效。
|
|
|
|
|
|
/// </para>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>已完成的任务</returns>
|
|
|
|
|
|
public Task RebuildAllAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 直接返回已完成的 Task,不执行任何操作。
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|