Джава:Проектирование с использованием синглтонов и дженериков

StackOverflow https://stackoverflow.com/questions/603827

Вопрос

Я использую интерфейс под названием Predicate, который используется для просеивания коллекций.Например, я могу определить

public class BlackCatPredicate implements Predicate<Cat> {
  public boolean evaluate( Cat c ) {
       return c.isBlack();
  }
}

а затем использовать какую-нибудь утилиту findAll( Collection<T> coll, Predicate<T> pred) метод, позволяющий применить предикат к коллекции кошек и получить только черные и т. д.

Мой вопрос таков:Я нахожу черных кошек по всему коду, поэтому нет необходимости снова и снова создавать экземпляр BlackCatPredicate.Он должен иметь только один экземпляр.(Синглетон?) Но потом, в процессе написания множества предикатов, мне не хочется реализовывать каждый из них как синглтон.Итак, какой здесь правильный дизайн?

Это было полезно?

Решение

Я бы использовал константу анонимного класса и поместил ее в класс, с которым она работает:

public class Cat{
    public static final Predicate<Cat> BLACK_PREDICATE = new Predicate<Cat>(){
            public boolean evaluate( Cat c ) {
                return c.isBlack();
            }
        };

    // Rest of the Cat class goes here
}

Если у предиката есть параметры, вы можете использовать статический фабричный метод.

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

Другие советы

Что-то вроде этого должно работать:

class Predicates
{
    private static class BlackCatPredicate implements Predicate<Cat> 
    {
        public boolean evaluate(final Cat c) 
        {
            return c.isBlack();
        }
    }

    private static final BlackCatPredicate = new BlackCatPredicate(); 


    public static Predicate<Cat> getBlackCatPredicate()
    {
        return (blackCatPredicate);
    }
}

Вы можете создать универсальную фабрику, которая принимает любой предикат в качестве аргумента типа, а затем генерирует один экземпляр для данного типа предиката.

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

Я бы не стал беспокоиться о создании дополнительных BlackCatPredicate экземпляры вообще.

Если ты не любишь писать new BlackCatPredicate() повсюду вы, конечно, можете добавить статический фабричный метод, чтобы вы могли писать BlackCatPredicate.getInstance() вместо.Еще одним вариантом было бы создать отдельный класс, чтобы вы могли писать CatPredicates.getBlackCatPredicateInstance().

Однако это предназначено только для абстрагирования создания предиката от клиентского кода и не имеет ничего общего с реальным созданием объекта.Работа с недолговечными объектами — одна из вещей, которую JVM делает лучше всего, поэтому необходимо создать кучу дополнительных BlackCatPredicate экземпляров и их немедленный отказ ни в малейшей степени не повлияет на вашу производительность.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top