Как правильно реализовать мой интерфейс Java с внутренним классом? - PullRequest
0 голосов
/ 10 сентября 2018

У меня был блок кода, который записывал события в файл журнала:

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();
    }
}

Как использовать эту новую функциональность?

1 Ответ

0 голосов
/ 10 сентября 2018

Я хочу, чтобы мой код был очень чистым, поэтому я хотел сделать весь файл Ввод / вывод внутри интерфейса, поэтому я создал внутренний класс

Объявление класса в интерфейсе не обязательно "чистый".
Кроме того, это будет не внутренний класс, а статический класс, поскольку класс объявлен в интерфейсе.
Все это противоречит интуиции. Класс является реализацией, а интерфейс - 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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...