Статьи

Завод без IF-ELSE

Объектно-ориентированный язык обладает очень мощной функцией полиморфизма, он используется для удаления if / else или переключения регистра в коде.

Код без условий легко читается. Есть несколько мест, где их нужно поместить, и одним из таких примеров является класс Factory / ServiceProvider.

Я уверен, что вы видели фабричный класс с IF-ELSEIF, который продолжает расти.

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

Я буду использовать приведенный ниже фрагмент кода в качестве примера:

01
02
03
04
05
06
07
08
09
10
11
public static Validator newInstance(String validatorType) {
        if ("INT".equals(validatorType))
            return new IntValidator();
        else if ("DATE".equals(validatorType))
            return new DateValidator();
        else if ("LOOKUPVALUE".equals(validatorType))
            return new LookupValueValidator();
        else if ("STRINGPATTERN".equals(validatorType))
            return new StringPatternValidator();
        return null;
    }

отражение

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

1
2
3
public static Validator newInstance(String validatorClass) {
        return Class.forName(validatorClass).newInstance();    
    }

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

карта

Карта может использоваться для отображения фактического экземпляра класса на какое-то понятное имя:

01
02
03
04
05
06
07
08
09
10
11
Map<String, Validator> validators =  new HashMap<String,Validator>(){
        {
            put("INT",new IntValidator());
            put("LOOKUPVALUE",new LookupValueValidator());
            put("DATE",new DateValidator());
            put("STRINGPATTERN",new StringPatternValidator());
        }
    };
    public Validator newInstance(String validatorType) {
        return validators.get(validatorType);
    }

Это также выглядит аккуратно без лишних размышлений.

Enum

Это интересный:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
enum ValidatorType {
    INT {
        public Validator create() {
            return new IntValidator();
        }
    },
    LOOKUPVALUE {
        public Validator create() {
            return new LookupValueValidator();
        }
    },
    DATE {
        public Validator create() {
            return new DateValidator();
        }
    };
    public Validator create() {
        return null;
    }
}
 
public Validator newInstance(ValidatorType validatorType) {
    return validatorType.create();
}

Этот метод использует метод enum для удаления условия, одна из проблем заключается в том, что вам нужен Enum для каждого типа. Вы не хотите создавать тонны из них!

Мне лично нравится этот метод.

Вывод

Если-либо или случай переключения делает код трудным для понимания, мы должны стараться избегать их в максимально возможной степени. Языковая конструкция должна использоваться, чтобы избежать некоторых случаев переключения.

Мы должны попытаться написать код без IF-ELSE, и это заставит нас найти лучшее решение.

Ссылка: Фабрика без IF-ELSE от нашего партнера JCG Ашкрит Шарма в блоге « Готовы ли вы» .