当前,我们有一个学校项目,其中我们的应用程序从具有特定格式的文件中获取输入,在MySQL中创建一个表并用数据填充它。在编写此代码时,我注意到我使用了很多依赖关系,我以前已经读过这些依赖关系是一个坏习惯。减少耦合并不是一个真正的大话题。到处搜索,我发现大多数答案都是关于接口的。我认为它们对我来说不是足够清晰的答案,而且不重复方法似乎也无济于事。

如何松开代码中的耦合?有什么好的一般提示和技巧吗?

PS:void showTable和stringBuilderShowTable没有实现,也无法正常工作。

public class DBService {
    DBConnection dbc;
    Connection con;
    //Statement stmt;


    public DBService()
    {
        dbc = new DBConnection();
        con = dbc.getConnection();
    }

    public void copyFile(String fileName, String tableName) throws SQLException {
        DataManager dm = new DataManager();
        dm.sortData(fileName);
        createTable(fileName, tableName, con);
        insertData(fileName, tableName, con);

    }
    public void showTable (String tableName)
    {
        try {
            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery
                    ("SELECT * FROM " + tableName);
            System.out.println("id  name    job");
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String job = rs.getString("job");
                System.out.println(id+"   "+name+"    "+job);
            }
        }
        catch(SQLException e){
            System.out.println("SQL exception occured" + e);
        }

    }

    public void createTable(String fileName, String tableName, Connection con) throws SQLException {
        try (Statement stmt2 = (Statement) con.createStatement())
        {
            String query1 = stringBuilderMeta(fileName, tableName);
            stmt2.execute(query1);

            if (stmt2.getWarnings() == null)
            {
                System.out.println("\n### Table " + tableName + " is created");

            } else
            {
                System.out.println("### " + stmt2.getWarnings());
            }
            stmt2.close();
        }
    }

    public void insertData(String fileName, String tableName, Connection con) throws SQLException
    {
        try (Statement stmt = (Statement) con.createStatement())
        {
            String query1 = stringBuilderData(fileName, tableName);
            stmt.execute(query1);

            if (stmt.getWarnings() == null)
            {
                System.out.println("\n### Table " + tableName + " has been successfully filled");

            } else
            {
                System.out.println("### " + stmt.getWarnings());
            }
            stmt.close();
        }
    }
    public String stringBuilderMeta(String fileName, String tableName)
    {
        DataManager dm = new DataManager();
        dm.sortData(fileName);


        StringBuilder builder = new StringBuilder();
        builder.append("" + "Create table ").append(tableName).append(" (\n");

        for (int i = 0; i < dm.fileMetaData.size();i++) {
            DataFromFile d = (DataFromFile)dm.fileMetaData.get(i);
            String test = d.getName();
            String test2 = d.getDatatype();
            String test3 = d.getLimit();
            if(i < (dm.fileMetaData.size()-1))
            {
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append("),\n");
            }
            else{
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append(")\n");
            }

        }
        builder.append(");");




        String string = builder.toString();
        return string;
    }

    public String stringBuilderShowTable(String fileName, String tableName)
    {
        DataManager dm = new DataManager();
        dm.sortData(fileName);


        StringBuilder builder = new StringBuilder();
        //builder.append("" + "SELECT * FROM " + tableName + ""

        for (int i = 0; i < dm.fileMetaData.size();i++) {
            DataFromFile d = (DataFromFile)dm.fileMetaData.get(i);
            String test = d.getName();
            String test2 = d.getDatatype();
            String test3 = d.getLimit();
            if(i < (dm.fileMetaData.size()-1))
            {
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append("),\n");
            }
            else{
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append(")\n");
            }

        }
        builder.append(");");




        String string = builder.toString();
        System.out.print(string);
        return string;
    }

    public String stringBuilderData(String fileName, String tableName)
    {
        DataManager dm = new DataManager();
        dm.sortData(fileName);
        int counter = 0;
        int counter2 = dm.reader.wordsPerLine;

        StringBuilder builder = new StringBuilder();

        for(int j = 0; j < dm.boo; j++)
        {
            builder.append("" + "INSERT INTO ").append(tableName).append (" (");
            for (int i = 0; i < dm.fileMetaData.size(); i++) {
                DataFromFile d = (DataFromFile) dm.fileMetaData.get(i);
                if (i < (dm.fileMetaData.size() - 1)) {
                    builder.append(d.getName()).append(", ");
                } else {
                    builder.append(d.getName());
                }

            }
            builder.append(")\n").append("VALUES (");
            for (int i = counter; i < counter2; i++) {
                if (i < (counter2 - 1)) {
                    builder.append("'" + dm.fileData.get(i) + "'" + ",");
                } else {
                    builder.append("'" + dm.fileData.get(i) + "'");
                }
            counter++;
            }
            counter2 = counter2+dm.reader.wordsPerLine;
            builder.append(");\n");
        }
        String string = builder.toString();
        System.out.print(string);
        return string;
    }
}

最佳答案

这是一个大问题。标准应用程序体系结构中的许多内容都与去耦(以及相关的关注点分离)有关。

您可能会从传统的OO设计模式中获得一些想法:https://en.wikipedia.org/wiki/Design_Patterns

一种方法是与具有定义角色(可能分为体系结构层,通常通过接口交互)的对象进行协作。一个应用程序可能具有一个表示层(进一步划分为MVC结构),用于向用户显示事物;一个数据访问层,用于与数据库对话;以及介于两者之间的服务层……而不是一个对象来完成所有这些事情。整个课程可能专门针对不跨那些类型的体系结构层流失的对象编写学科。

您可能还需要查看“控制反转”或“依赖注入”。有几个框架可以使用,但是基本思想只是这样:一个类需要使用一个实现SomeDependencyINeed接口的对象,但是与其直接说myVariable = new ImplementationOfSomeDependencyINeed();而不是直接提供SomeDependencyINeed引用的方式,而是提供了一种方法。 (构造函数参数或setter方法)。像Spring这样的框架提供了“控制容器反转”(或IoC容器),通常可以提供(“注入”)依赖实例。或没有框架,您可能需要承担某种责任的构建者或配置者对象。

麻烦的是,一个学校项目通常不够大-更重要的是,通常没有足够长时间的维护-才能展示这些技术的好处。因此,作为一名学生,如果您愿意做的话,您会看到所有的成本-花费更长的时间来启动和运行,有时您会以一种似乎不必要的特定方式来做事情-但您通常不会看到任何好处。

08-08 08:36