【问题标题】:What is a class good for if it only delegates and does nothing else?如果一个类只代表而不做其他事情,它有什么用?
【发布时间】:2018-05-07 20:38:49
【问题描述】:

这里的例子取自书中:Professional Java Development with the Spring Framework

在AOP章节中,我们以一个AccountManager实现为例:

public class AccountManagerImpl implements AccountManager {
    private MailSender mailSender;
    private SimpleMailMessage message;
    private AccountDao accountDao;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setMessage(SimpleMailMessage message) {
        this.message = message;
    }

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    private void sendMail(Exception ex) {
        SimpleMailMessage msg = new SimpleMailMessage(this.message);
        msg.setText("Encountered exception " + ex.getMessage());
        this.mailSender.send(msg);
    }

    public Account getAccount(String accountId) throws AccountNotFoundException, DataAccessException {
        try {
            return this.accountDao.findAccount(accountId);
        } catch (AccountNotFoundException ex) {
            sendMail(ex);
            throw ex;
        } catch (DataAccessException ex) {
            sendMail(ex);
            throw ex;
        }
    }

    public void createAccount(Account account) throws DataAccessException, {
        try {
            if (isInvalid(account)) {
                throw new InvalidAccountException(account);
                this.accountDao.saveAccount(account);
            } catch(IOException ex){
                sendMail(ex);
                throw ex;
            } catch(DataAccessException ex){
                sendMail(ex);
                throw ex;
            }
        }
    }
}

然后解释了面向方面编程的所有优点,进行了一些配置以将sendMail(ex)移动到一个方面,我们最终得到:

public class AccountManagerImpl implements AccountManager {
    private AccountDao accountDao;

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    public Account getAccount(String accountId)
            throws AccountNotFoundException, DataAccessException {
        return this.accountDao.findAccount(accountId);
    }

    public void createAccount(Account account) throws DataAccessException {
        this.accountDao.saveAccount(account);
    }
}

引自本书本身:

结果是一个重大改进。 AccountManager 纯粹是 负责账户管理,让代码更简单, 更易于阅读和维护。异常通知机制是 干净地模块化,因此可以单独维护 商业逻辑。例如,一位开发人员现在可以修改 无需修改大量异常通知策略 在传统方法中会受到影响的文件。

在我看来,AccountManagerImpl 之前实际上是一个 Manager,而第二个示例只是一场灾难。

从第二个版本的实现中可以看出,Manager 类根本没有做任何事情,而是将所有事情委托给一个AccountDao

我的具体问题是:为什么要有这个实现(第二版)?我们也可以将 Aspect 应用于AccountDao,不是吗?

【问题讨论】:

  • 感谢您的快速回归。超级快!

标签: java spring architecture aop software-design


【解决方案1】:

我同意管理器的核心功能在重构后看起来并不令人信服。但这可能只是因为作者没有花太多时间寻找更好的例子。

方面的要点是:提取可以在不同类中找到的横切功能。换句话说:你发现一个或多个类花费代码做的事情并不真正适合每个类的核心职责。然后,您将这个“非核心功能”抽象为方面 - 允许您转向 AOP 工具。这样您就可以通过让该工具将相应的代码移动到方面来整理您的核心业务逻辑。

【讨论】:

    【解决方案2】:

    如果 Manager 类是一个外观,那么它的目的是隐藏其成员交互的复杂性。在您的示例中,它有点太简单了,因此好处并不明显。但是考虑到对 DAO 的调用不是那么直接(需要一些锅炉代码),那么 Manager 类隐藏了复杂性是件好事。或者假设 DAO 需要与其他对象进行一些交互,那么 Manager 类也隐藏了复杂性。对于外部客户来说,调用很简单。

    【讨论】:

      猜你喜欢
      • 2018-12-09
      • 2016-05-01
      • 1970-01-01
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 2020-07-21
      • 2015-11-01
      • 2010-10-24
      相关资源
      最近更新 更多