我怎样才能在不重复的情况下重写这些方法?

Posted

技术标签:

【中文标题】我怎样才能在不重复的情况下重写这些方法?【英文标题】:How can i rewrite this methods without duplication? 【发布时间】:2018-02-20 07:31:51 【问题描述】:

怎样才能使这段代码不重复? 这种方法类似。

创建电话号码的方法:

   private List<String> createPhoneNumbers(String sqlStatement, Long id) 
        List<String> phones = new ArrayList<>();
        try (PreparedStatement statement = this.connection.prepareStatement(sqlStatement)) 
            statement.setLong(1, id);
            try (ResultSet resultSet = statement.executeQuery()) 
                while (resultSet.next()) 
                    phones.add(resultSet.getString("phoneNumber"));
                
                return phones;
            
         catch (SQLException e) 
            e.printStackTrace();
            return null;
        
    

创建好友列表的方法:

   private List<Account> createFriendList(String sqlStatement, Long id) 
        List<Account> friends = new ArrayList<>();
        try (PreparedStatement statement = this.connection.prepareStatement(sqlStatement)) 
            statement.setLong(1, id);
            try (ResultSet resultSet = statement.executeQuery()) 
                while (resultSet.next()) 
                    friends.add(createSimpleElement(resultSet));
                
                return friends;
            
         catch (SQLException e) 
            e.printStackTrace();
            return null;
        
    

创建组列表的方法:

   private List<Group> createGroupList(String sqlStatement, Long id) 
        List<Group> groups = new ArrayList<>();
        try (PreparedStatement statement = this.connection.prepareStatement(sqlStatement)) 
            statement.setLong(1, id);
            try (ResultSet resultSet = statement.executeQuery()) 
                while (resultSet.next()) 
                    groups.add(createGroupFromResultSet(resultSet));
                
                return groups;
            
         catch (SQLException e) 
            e.printStackTrace();
            return null;
        
    

这是我非常糟糕的解决方案。

 //field values: 1- create String, 2 - createAccount, 3 - createGroup
private <E> List<E> createList(String selectSql, Long id, int field) 
    List<E> list = new ArrayList<>();
    try (PreparedStatement statement = this.connection.prepareStatement(selectSql)) 
        statement.setLong(1, id);
        try (ResultSet resultSet = statement.executeQuery()) 
            while (resultSet.next()) 
                switch (field) 
                    case 1:
                        list.add((E) resultSet.getString("phoneNumber"));
                        break;
                    case 2:
                        list.add((E) createSimpleElement(resultSet));
                        break;
                    case 3:
                        list.add((E) createGroupFromResultSet(resultSet));
                        break;
                
            
            return list;
        
     catch (SQLException e) 
        e.printStackTrace();
        return null;
    

我可以阅读什么来解决我的代码中的类似问题?

【问题讨论】:

不要。拥有只做一件事并做好的方法是一种很好的做法。如果需要,您可以随时使用接口或抽象类。 你可以阅读设计模式并通过编写代码来尝试它们,tutorialspoint.com/design_pattern 【参考方案1】:

在我看来,您应该查看Spring JDBC,它是基于回调的JdbcTemplate 方法。它将所有样板文件(数据库连接、事务、异常翻译等)从您手中抽象出来,让您专注于应用程序代码。

示例:

List<Actor> actors = this.jdbcTemplate.query(
        "select first_name, last_name from t_actor",
        new RowMapper<Actor>() 
            public Actor mapRow(ResultSet rs, int rowNum) throws SQLException 
                Actor actor = new Actor();
                actor.setFirstName(rs.getString("first_name"));
                actor.setLastName(rs.getString("last_name"));
                return actor;
            
        );

【讨论】:

【参考方案2】:

“将变化与保持不变的内容分开” - Head First Design Pattern。

您可以将从Resultset(更改)中提取数据的逻辑与准备语句和执行语句(不更改)分开

如果您不想从任何框架支持中获得帮助,您可以执行以下操作

public interface GenericDao 
    ResultSet find(String sqlStatement, Long id);


public class GenericDaoImpl extends GenericDao 
    @Override
    public ResultSet find(String sqlStatement, Long id) 
        try (PreparedStatement statement = this.connection.prepareStatement(sqlStatement)) 
            statement.setLong(1, id);
            try (ResultSet resultSet = statement.executeQuery()) 
                return resultSet;
            
         catch (SQLException e) 
            e.printStackTrace();
            return null;
        
    


public interface ContactDao 
    List<String> createPhoneNumbers(String sqlStatement, Long id);
    List<Account> createFriendList(String sqlStatement, Long id);
    List<Group> createGroupList(String sqlStatement, Long id);


public class ContactDaoImpl extends ContactDao
    private GenericDao genericDao;

    ContactDaoImpl(GenericDao genericDao) 
        this.genericDao = genericDao;
    

    @Override
    public List<String> createPhoneNumbers(String sqlStatement, Long id) 
        ResultSet resultSet = this.genericDao.executeSqlQuery(sqlStatement, id);
        while (resultSet.next()) 
            phones.add(resultSet.getString("phoneNumber"));
        
        return phones;
    

    @Override
    public List<Account> createFriendList(String sqlStatement, Long id) 
        ResultSet resultSet = this.genericDao.executeSqlQuery(sqlStatement, id);
        while (resultSet.next()) 
            friends.add(createSimpleElement(resultSet));
        
        return friends;
    

    @Override
    public List<Group> createGroupList(String sqlStatement, Long id) 
        ResultSet resultSet = this.genericDao.executeSqlQuery(sqlStatement, id);
        while (resultSet.next()) 
            groups.add(createGroupFromResultSet(resultSet));
        
        return groups;
    

【讨论】:

以上是关于我怎样才能在不重复的情况下重写这些方法?的主要内容,如果未能解决你的问题,请参考以下文章

更改 Git 中的旧提交 [重复]

如何在不使用 each() 的情况下重写此函数? [复制]

在不更改 url 的情况下访问脚本

如何在不登录firebase / js的情况下注册用户[重复]

在不登录[重复]的情况下验证Google云端硬盘上传

如何在不使用 Set 的情况下有效地从数组中删除重复项