Pull to refresh

Comments 15

Это был пример нетривиального, многошагового рефакторинга.


А где сам процесс-то?

Увидел описание проблемы. Увидел решение. А процесс рефакторинга (сами шаги) не увидел.
спасибо за замечание, расписал
В свою очередь вы могли бы пойти дальше и сделать так:
    public static MyRequest createPostRequest() {
        return createRequest("POST");
    }

    public static MyRequest createGetRequest() {
        return createRequest("Get");
    }

    private static MyRequest createRequest(String method) {
        MyRequest request = new MyRequest();
        request.setMethod(method);
        request.setContentType("application/x-www-form-urlencoded");
        return request;
    }


еще интересные примеры есть с передачей функций в качестве аргумента, для языков, поддерживающих функции первого класса. Типичный пример хорошей реализации — LINQ в .Net
только вы забыли вынести contentType.
Основы борьбы с неявным дублированием кода. Боюсь представить явное :)
В смысле за ошибки в как в примере канделябром надо бить, до такого в принципе не должно было дойти
На самом деле, практика оптимизации производительности/использования памяти кода показывает, что иногда лучше сделать 5 одинаковых по структуре куска кода, но сэкономить на времени создания класса и передаче туда-сюда параметров. :(

Красивый код очень часто вступает в противоречие с оптимальным кодом :'(
Красивый код всегда можно ускорить, в соответствии с рекомендациями профайлера, а вот из быстрого говнокода сделать сопровождаемую конфетку будет затруднительно…
Достаточно редко. Я говорил про данный пример, и String-oriented код явно не оптимальный.
> но сэкономить на времени создания класса и передаче туда-сюда параметров. :(
Экономия на спичках. Гораздо быстрей и проще сразу писать правильно, а потом, если вдруг будет затык уже оптимизировать. И уверяю вас, затык с производительностью будет совсем не из-за передачи параметров.
Бить надо, конечно, но есть унаследованные проекты, а в Индию к их разработчикам зачастую далеко ехать.
Для этой задачи, я бы рекомендовал определить интерфейс сервиса, и отдать его программистам использующим сервис. А реализацию этого интерфейса поручить другому программисту.
Определяем интерфейс сервиса:
public class MyServerException extends RuntimeException {
// ...
}

public interface PhotoInfo {
// ...
}

public interface MyServerSession {
    void login(String username, char[] password) throws MyServerException;
    boolean isLoggedIn();
    List<PhotoInfo> getUserPhotos(int userId) throws MyServerException;
    void uploadPhoto(Bitmap photo, int userId) throws MyServerException;
}


Реализацию поручаем другому программисту.
class MyServerSessionImpl implements MyServerSession {
    MyServerSessionImpl(String serverUrl) {
    }
    // ...
}


Дублирование кода — не происходит.
Параллельная работа как минимум двух программистов — происходит.
Протокол взаимодействия с сервером — сокрыт от всей системы.
Возможность независимо юнит-тестировать обе части системы — в наличии.
Самодокументирующийся код — очень похоже.
Однобоко получилось. Борьба с дублированием кода приводит к увеличению количества зависимостей, что плохо. Эту сторону медали тоже надо освещать.
Проблема обычно не в том, что нужно объединить однотипные участки в вызов функции, а в том, что когда проекту года три-четыре уже сам не помнишь где и как что было сделано. Поскольку предметная область проекта не меняется, то многие процедуры весьма похожи, но раскиданы по модулям и тупо найти их — вот это задача.

Для себя решил, что ответ на такую задачу есть — спецификации программных интерфейсов должны быть разработаны до кодирования. Это нудно, зато весьма действенно. Но как коммунизм — утопично на практике. ТЗ живет своей жизнью почти всегда.

Пример же в статье тривиален и его встречал у себя каждый, ну как бы совершенно понятно, что если что то фигурирует дважды — то это зло. Это и в базах данных, и в коде, и вообще в IT дублирование — почти всегда ошибка. Исключения правда тоже есть, например, простейшая оптимизация быстродействия — суть избавление от лишних вызовов подпрограмм, т.е. как раз искусственное дублирование кода.

Итого: как все-таки бороться с дублированием в реальной жизни? Заголовок обнадеживал. Но пока увы. Может будет продолжение?
Sign up to leave a comment.

Articles