设计模式-装饰器

定义

装饰器模式是一种结构型设计模式,它允许你通过将对象放入包含行为的特殊封装对象中来为原对象动态添加新的行为或功能。简单来说,它的核心思想是:不通过修改原有类代码的方式,而是通过“包装”的方式,来动态地扩展一个对象的功能。

核心角色

装饰器模式通常包含以下四个角色:
组件接口:定义一个对象接口,可以动态地给这些对象添加职责。这是所有被装饰对象和装饰器对象的共同父类。
具体组件:实现组件接口,定义了最基本的对象,也就是我们最终要装饰的核心对象。
装饰器基类:实现组件接口,并持有一个组件接口的实例(通过组合的方式)。这个基类通常是一个抽象类,目的是让子类来扩展功能。
具体装饰器:继承自装饰器基类,负责向组件添加新的职责。每个具体装饰器都包装了一个组件,并为其增强功能。

实例

queryInfo()不能随意变动,唯有扩展。

组件接口

关注UserVO queryInfo()。

public interface IUserService extends IService<User> {

    /**
     * 详细信息ByUserId
     *
     * @param userId
     * @return
     */
    UserVO queryInfo(Long userId);

    /**
     * 分页查询
     *
     * @param userPageQuery
     * @return
     */
    Page<UserVO> queryPage(UserPageQuery userPageQuery);
    
    /**
     * 分页查询ByXml
     *
     * @param userPageQuery
     * @return
     */
    Page<UserVO> queryPageByXml(UserPageQuery userPageQuery);

    /**
     * 列表查询
     *
     * @param userQuery
     * @return
     */
    List<UserVO> queryList(UserQuery userQuery);
    
    /**
     * 用户信息ByUserName
     *
     * @param userName
     * @return
     */
    User queryByUserName(final String userName);

    /**
     * 新增
     *
     * @param userDTO
     */
    void add(UserDTO userDTO);

    /**
     * 编辑
     *
     * @param userDTO
     */
    void edit(UserDTO userDTO);

    /**
     * 删除
     *
     * @param userIds
     */
    void del(Long[] userIds);
    
}

具体组件

关注UserVO queryInfo()。

@Service
@RequiredArgsConstructor
@Primary
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final ApplicationEventPublisher applicationEventPublisher;

    private final IUserLogService userLogService;

    private final AsyncTaskExecutor asyncTaskExecutor;

    @Override
    // 这里使用了SpringCache,value=统一前缀;key=key的一部分【支持SpEL】
//    @Cacheable(value = "userInfo", key = "#userId")
    public UserVO queryInfo(Long userId) {
        User user = getById(userId);
        return BeanUtil.copyProperties(user, UserVO.class);
    }

    @Override
    // 动态数据源
//    @DataSource(DataSourceType.SLAVE)
    public Page<UserVO> queryPage(UserPageQuery userPageQuery) {
        BasePageVO<User> page = this.lambdaQuery()
                .in(CollectionUtil.isNotEmpty(userPageQuery.getUserIds()), User::getUserId, userPageQuery.getUserIds())
                .eq(StrUtil.isNotBlank(userPageQuery.getUserName()), User::getUserName, userPageQuery.getUserName())
                .eq(ObjectUtil.isNotNull(userPageQuery.getUserId()), User::getUserId, userPageQuery.getUserId())
                .like(StrUtil.isNotBlank(userPageQuery.getNickName()), User::getNickName, userPageQuery.getNickName())
                .page(userPageQuery.page());

        return PageUtils.toPage(page, UserVO.class);
    }

    @Override
    public Page<UserVO> queryPageByXml(UserPageQuery userPageQuery) {
        return this.baseMapper.queryPageByXml(userPageQuery, userPageQuery.page());
    }

    @Override
    public List<UserVO> queryList(UserQuery userQuery) {
        List<User> list = this.lambdaQuery()
                .eq(StrUtil.isNotBlank(userQuery.getUserName()), User::getUserName, userQuery.getUserName())
                .eq(ObjectUtil.isNotNull(userQuery.getUserId()), User::getUserId, userQuery.getUserId())
                .like(StrUtil.isNotBlank(userQuery.getNickName()), User::getNickName, userQuery.getNickName())
                .list();

        asyncTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                userLogService.addDefault();
            }
        });

        return BeanUtil.copyToList(list, UserVO.class);
    }

    @Override
    public User queryByUserName(final String userName) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUserName, userName);
        return getOne(wrapper);
    }

    @Override
    // 动态数据源
//    @DataSource
    @Transactional(rollbackFor = Exception.class)
    public void add(UserDTO userDTO) {
        User user = BeanUtil.copyProperties(userDTO, User.class);
        save(user);
        // 发布事件
        applicationEventPublisher.publishEvent(new UserEvent(this, user));
    }

    @Override
    public void edit(UserDTO userDTO) {
        User user = getById(userDTO.getUserId());
        BeanUtil.copyProperties(userDTO, user, CopyOptions.create().setIgnoreNullValue(true));
        // 注意乐观锁,不需前端传递
        updateById(user);
    }

    @Override
    public void del(Long[] userIds) {
        if (userIds == null || userIds.length == 0) {
            return;
        }
        removeBatchByIds(Arrays.asList(userIds));
    }
}

装饰器基类

对UserVO queryInfo()进行增强;新增UserVO test()。

public abstract class DecoratorUserService implements IUserService {

	// 持有一个组件对象的引用
    protected IUserService userService;

    public DecoratorUserService(IUserService userService) {
        this.userService = userService;
    }

    public abstract UserVO queryInfo(Long userId);


    public abstract UserVO test(Long userId);
}

具体装饰器

对UserVO queryInfo()进行增强;新增UserVO test();其它方法可暂时不实现。

@Component
// 具体装饰器
public class DecoratorUserServiceImpl extends DecoratorUserService {

    private final IUserLogService userLogService;

    public DecoratorUserServiceImpl(IUserService userService, IUserLogService userLogService) {
        super(userService);
        this.userLogService = userLogService;
    }

    @Override
    public UserVO queryInfo(Long userId) {
        // 原功能
        UserVO result = userService.queryInfo(userId);
        // 在原功能的基础上扩展功能
        LambdaQueryWrapper<UserLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserLog::getUserId, userId);
        List<UserLog> userLogs = userLogService.list(wrapper);
        result.setUserLogs(userLogs);
        return result;
    }

    @Override
    public UserVO test(Long userId) {
        // 也可以增加原组件没有的功能
        return null;
    }

    @Override
    public Page<UserVO> queryPage(UserPageQuery userPageQuery) {
        return null;
    }

    @Override
    public Page<UserVO> queryPageByXml(UserPageQuery userPageQuery) {
        return null;
    }

    @Override
    public List<UserVO> queryList(UserQuery userQuery) {
        return null;
    }

    @Override
    public User queryByUserName(String userName) {
        return null;
    }

    @Override
    public void add(UserDTO userDTO) {

    }

    @Override
    public void edit(UserDTO userDTO) {

    }

    @Override
    public void del(Long[] userIds) {

    }

    @Override
    public boolean saveBatch(Collection<User> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<User> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean updateBatchById(Collection<User> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(User entity) {
        return false;
    }

    @Override
    public User getOne(Wrapper<User> queryWrapper, boolean throwEx) {
        return null;
    }

    @Override
    public Optional<User> getOneOpt(Wrapper<User> queryWrapper, boolean throwEx) {
        return Optional.empty();
    }

    @Override
    public Map<String, Object> getMap(Wrapper<User> queryWrapper) {
        return null;
    }

    @Override
    public <V> V getObj(Wrapper<User> queryWrapper, Function<? super Object, V> mapper) {
        return null;
    }

    @Override
    public BaseMapper<User> getBaseMapper() {
        return null;
    }

    @Override
    public Class<User> getEntityClass() {
        return null;
    }
}

测试结果

@RestController
@Api(tags = "用户管理")
@RequestMapping("/user")
public class UserController {

    // 原组件
    private final IUserService userService1;

    // 具体装饰器
    private final IUserService userService2;

    public UserController(@Qualifier("userServiceImpl") IUserService userService1, @Qualifier("decoratorUserServiceImpl") IUserService userService2) {
        this.userService1 = userService1;
        this.userService2 = userService2;
    }

    // 原组件功能
    @ApiOperation(value = "基础信息")
    @GetMapping("/baseInfo/{userId}")
    public Result<UserVO> queryBaseInfo(@PathVariable Long userId) {
        UserVO result = userService1.queryInfo(userId);
        return Result.success(result);
    }

    // 具体装饰器功能
    @ApiOperation(value = "详细信息")
    @GetMapping("/info/{userId}")
    public Result<UserVO> queryInfo(@PathVariable Long userId) {
        UserVO result = userService2.queryInfo(userId);
        return Result.success(result);
    }
}

装饰器

posted @ 2025-09-08 10:57  南翔技校毕业后  阅读(5)  评论(0)    收藏  举报