2016-12-15 1 views
0

У меня есть специальный чехол, как показано ниже. У меня есть класс Listener и класс Uploader. Класс слушателя прослушивает сообщения по сети, обрабатывает их и создает из него еще один маленький объект.Неплохая практика иметь класс вспомогательного помощника?

public class Listener { 
    Uploader uploader; 

    Listener(String location) { 
     uploader = new Uploader(location); 
    } 

public void listen(Message msg) { 
    ProcessedObject obj = process(msg); 
    uploader.add(obj); 
} 

public void terminate() { 
    if (null != uploader) { 
     uploader.finish(); 
    } 
} 

}

Класс Uploader принимает один объект с помощью метода добавления, и решает, когда Uploader. Для этого он ведет список. Он также имеет строку местоположения, которая относится к одному слушателю. Вот суть:

/** 
* This class is not thread safe, and an object should not be shared across threads 
* 
*/ 
public class Uploader { 
    String location; 
    List<ProcessedObject> objects; 

    Uploader(String location) { 
     this.location = location; 
    } 

    void add(ProcessedObject obj) { 
     objects.add(obj); 

     if (objects.size() > PARTITION_SIZE) { 
      uploadObjects(objects); 
      objects.clear(); 
     } 
    } 

    void finish() { 
     uploadObjects(objects); 
    } 
} 

Таким образом, загружать, если количество объектов больше, чем partition_size. В приложении есть несколько слушателей, каждый из которых работает в отдельном потоке. У каждого слушателя будет свой собственный объект uploader. Я четко упомянул, что этот класс не является потокобезопасным, в javadoc.

Теперь мой вопрос: это хорошая практика?

Некоторые из моих коллег говорят, что это не очень хорошая практика и предлагают использовать статический метод для загрузки, а не создавать экземпляр загрузчика. Но мой аргумент заключается в том, что мой класс слушателя будет беспорядочным (потому что тогда слушателю придется поддерживать подсчеты, а также проверять и загружать снова в конце до завершения для оставшихся объектов)

С моим подходом полное разбиение и загрузка логика доступна в классе загрузчика, поэтому она улучшает читаемость и удобство обслуживания.

Мой вопрос в том, что мой подход плохой практики (учитывая также, что я специально призываю, чтобы загрузчик не был потокобезопасным)?

Кроме того, есть ли какой-либо шаблон дизайна для того, что я пытаюсь сделать здесь? Если да, то какой?

Редактировать: Я принимаю Я не задал вопрос правильно. Меня здесь не интересует раздел или выгрузка. Просто подход к созданию одного объекта класса Uploader для каждого потока, а также для создания без статичного класса Uploader со статическими методами для выполнения задания.

Независимо от того, загружаю ли я оставшиеся объекты, или вообще я должен разделять, это не проблема этого вопроса.

ответ

0

Вы можете комбинировать оба подхода, используя приватный статический ThreadLocal, чтобы удерживать Uploader.

Глядя на общую картину:

Я думаю, что ваши сотрудники имеют действительную точку. Учтите, что Uploader может быть в отдельном потоке или в пуле потоков. Все это может быть отвлечено и скрыто от слушателя. Затем Uploader может решить, имеет ли он достаточную работу, основанную на количестве элементов ИЛИ, если это была заданная длительность миллисекунд без получения большего количества элементов. Возможно, позволить Listener выполнять флеш/финишировать, но это не должно быть ... это требование для других кодеров.

+0

Если я не ошибаюсь, в этом случае мне придется вести общий список объектов, которые поток пользователей может контролировать и загружать через равные промежутки времени. Это то, что вы предлагаете? – Kartik

+0

@ Kartik это одна возможная реализация. или каждый поток слушателя может иметь связанный поток (ы) пользователя. я считаю, что он должен быть полностью прозрачным для слушателя. –

+0

Это действительно имеет смысл. Но даже в этом случае, это загрузчик, который должен поддерживать состояние для правильного разделения? – Kartik

0

Я думаю, вы задаете этот вопрос неверным образом. Вы спрашиваете, является ли это плохой практикой или нет.

Подумайте наоборот. На самом деле задача, которую вы решаете? Имеет ли смысл смысл? И ваша реализация хорошая?

Задача, которую вы решаете, заключается в «упаковке» нескольких объектов вместе для загрузки вместо их загрузки по одному.

Это может иметь смысл уменьшить количество загрузок. Но, возможно, нет, это зависит от того, сколько накладных расходов приходится на одну загрузку. Не зная ничего более, мое предположение состояло бы в том, что это может иметь смысл.

Теперь, ваша реализация хорошая? Ну ...

Прежде всего вы упомянули несколько потоков, поэтому вам нужно будет проявить особую осторожность, чтобы синхронизировать ваш список объектов.

Дальше, хорошо ли ждать PARTITION_SIZE? Что делать, если у вас есть только PARTITION_SIZE - 1 объектов?? Вы можете дождаться последнего навсегда, не отправляя другие объекты.

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

+0

1. У меня есть метод завершения, который вызывается в конце, чтобы дать возможность загружать, если количество объектов меньше PARTITION_SIZE – Kartik

+0

Есть ли гарантии, когда будет вызван 'terminate'? – lexicore

+0

1. Как я уже упоминал, объект uploader должен использоваться только внутри 1 потока. Это контракт этого класса, я упомянул его дважды в вопросе. 2. У меня есть метод завершения, который вызывается в конце, чтобы дать возможность загрузить, если количество объектов меньше PARTITION_SIZE 3. Да, это может произойти. У нас есть способы повторной попытки выйти за рамки данных классов. И данные, которые будут загружены, могут быть возвращены снова. Так что это действительно не проблема для нас Сказав все это, вопрос здесь больше об использовании статического метода и объекта uploader. – Kartik