У меня был блок кода, который записывал события в файл журнала:
Date rightNow = new Date();
File logfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), ("MyLogfile" + fileSDF.format(rightNow) + ".txt"));
FileOutputStream fos;
boolean documents_directory_exists = logfile.getParentFile().exists();
boolean documents_directory_created = true;
if (!documents_directory_exists) documents_directory_created = logfile.getParentFile().mkdirs();
if (documents_directory_created){
try {
fos = new FileOutputStream(logfile, true);
fos.write(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());
fos.close();
} catch (IOException ioe) {
Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, ioe.getMessage()));
}
} else {
Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, "Cannot create the necessary directories."));
}
У меня был этот код в нескольких местах, поэтому я подумал, что вставлю его в интерфейс, чтобы сделать свой код чище. Итак, я создал этот интерфейс:
public interface LogWriter {
void writeLog(LogEntry logEntry);
}
Где находится LogEntry:
public class LogEntry{
private String timestamp;
private boolean booean01;
private int someInt;
private boolean boolean02;
public LogEntry(timestamp, boolean01, someInt, boolean02){
this.timestamp = timestamp;
this.boolean01= boolean01;
this.someInt= someInt;
this.boolean02= boolean02;
}
// Getters and Setters
}
Я хочу, чтобы мой код был очень чистым, поэтому я хотел выполнять весь файловый ввод-вывод в интерфейсе, поэтому я создал внутренний класс:
public interface LogWriter {
void writeLog(LogEntry logEntry);
class WriteMeToTheLog {
LogEntry logEntry;
private static final SimpleDateFormat fileSDF = new SimpleDateFormat(Constants.ACCESS_LOGFILE_NAME_FORMAT);
public WriteMeToTheLog(LogEntry logEntry) {
this.logEntry = logEntry;
}
public void write(){
Date rightNow = new Date();
File logfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), ("MyLogfile" + fileSDF.format(rightNow) + ".txt"));
FileOutputStream fos;
boolean documents_directory_exists = logfile.getParentFile().exists();
boolean documents_directory_created = true;
if (!documents_directory_exists) documents_directory_created = logfile.getParentFile().mkdirs();
if (documents_directory_created){
try {
fos = new FileOutputStream(logfile, true);
fos.write(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());
fos.close();
} catch (IOException ioe) {
Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, ioe.getMessage()));
}
} else {
Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, "Cannot create the necessary directories."));
}
}
}
}
Вот где я теряю ОЧЕНЬ.
В одном из классов, где у меня был исходный блок кода, я реализовал этот новый интерфейс:
public class OneOfMyClasses extends BaseClass implements LogWriter {
public myMethod(){
// This is where I had the original block of code
// WHAT DO I DO HERE NOW???
}
@Override
public void writeLog(){
Date rightNow = new Date();
writeMeToTheLog(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());
writeMeToTheLog.write();
}
}
Как использовать эту новую функцию?
I want to keep my code very clean, so I wanted to do all of the file I/O within the interface, so I created an inner class
Объявление класса в интерфейсе не обязательно "чистым" .
Кроме того, это будет не внутренний класс, а статический класс, поскольку класс объявлен в интерфейсе.
Все это противоречит интуиции. Класс - это реализация, а интерфейс - это API. Звучит не очень хорошо, что API декларирует структуру реализации.
Что касается вашего вопроса, я думаю, что WriteMeToTheLog
(содержащий извлеченную вами логику ведения журнала) также должен реализовывать LogWriter
, поскольку он выглядит как реализация LogWriter
.
И класс клиента должен иметь зависимость от WriteMeToTheLog
, вероятно, как поле, установленное в конструкторе, хотя он все еще может реализовать LogWritter
, если это имеет смысл.
Это даст:
class WriteMeToTheLog implements LogWriter { ...}
А также :
public class OneOfMyClasses extends BaseClass implements LogWriter {
private LogWriter logWriter;
public OneOfMyClasses (LogWriter logWriter){
this.logWriter = logWriter;
}
@Override
public void writeLog(){
Date rightNow = new Date();
logWriter.write();
}
}
Теперь вы можете создать экземпляр клиентского класса, установив зависимость:
OneOfMyClasses o = new OneOfMyClasses(new WriteMeToTheLog(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());