JDBC - ослабить сцепление
В настоящее время у нас есть школьный проект, в котором наше приложение берет данные из файла определенного формата, создает таблицу в 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;
}
}
1 ответ
Это большой вопрос. Многое из того, что вошло в стандартную архитектуру приложений, связано с разделением (и связанным с ним разделением интересов).
Вы можете получить некоторые идеи из традиционных шаблонов проектирования ОО: https://en.wikipedia.org/wiki/Design_Patterns
Совместная работа объектов с определенными ролями (возможно, разделенными на архитектурные слои и обычно взаимодействующими через интерфейсы) является одним из методов. Прикладная программа может иметь уровень представления (дополнительно разделенный на структуру MVC) для отображения информации пользователю, уровень доступа к данным для связи с базой данных и уровень обслуживания между ними... вместо одного объекта, выполняющего все эти вещи. Целый курс может быть посвящен дисциплине написания объекта, который не распространяется на эти типы архитектурных слоев.
Вы также можете захотеть взглянуть на "инверсию управления" или "внедрение зависимости". Для этого есть несколько структур, но основная идея заключается только в следующем: класс должен использовать объект, который реализует интерфейс SomeDependencyINeed, но вместо того, чтобы прямо говорить myVariable = new ImplementationOfSomeDependencyINeed();
это дает возможность получить SomeDependencyINeed
ссылка (аргумент конструктора или метод установки). Фреймворк, такой как Spring, обеспечивает "инверсию контейнера управления" (или контейнера IoC), который обычно предоставляет ("внедряет") экземпляры зависимостей; или без фреймворка у вас может быть какой-то объект компоновщика или конфигуратора с такой ответственностью.
Проблема в том, что школьный проект обычно недостаточно велик - и, что более важно, обычно не поддерживается достаточно долго - чтобы продемонстрировать преимущества этих методов. Так что, как студент, если вы их выполняете, вы увидите все расходы - для того, чтобы приступить к работе, требуется больше времени, иногда вы делаете что-то определенным образом, что может показаться ненужным - но вы обычно не видите преимущества.