(Режим стратегии + заводской режим + карта) чехол переключателя в пакете Kill project

Java

Возьмите на себя новую задачу: подключитесь к третьему депозитарному учреждению, см. предыдущий код, используя регистр swith, чтобы определить, какое депозитарное учреждение использовать, логика реализации каждого депозитарного учреждения отличается.
Плохой запах кода: несколько слоев переключателей. Многослойный корпус коммутатора не прост в обслуживании, пришло время провести рефакторинг,

код перед оптимизацией

Для простоты понимания возьмем пример без бизнес-логики и на его основе проведем оптимизацию. Сейчас 12:47, возьми, к примеру, поедание фруктов после еды, хахаха (побег
Предположим, фрукты, которые мы можем выбрать, — это бананы, арбузы и яблоки. Если мы едим бананы, мы должны сначала очистить их, если мы едим арбузы, мы должны сначала разрезать их ножом для фруктов, если это яблоки, мы едим их прямо. Превратите эту сцену в код:

public class EatFruit {
    private static final String APPLE = "apple";
    private static final String BANANA = "banana";
    private static final String WATERMELON = "watermelon";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //选择的水果种类
        String fruitType = scanner.nextLine();

        switch (fruitType) {
            case APPLE:
                eatApple();
                break;
            case BANANA:
                eatBanana();
                break;
            case WATERMELON:
                eatWatermelon();
                break;
        }
    }

    private static void eatBanana() {
        System.out.println("吃香蕉了,需要先剥下皮");
    }

    private static void eatApple() {
        System.out.println("是苹果,可以直接吃");
    }

    private static void eatWatermelon() {
        System.out.println("吃西瓜了,但是还得弄把水果刀切一下先");
    }
}

Объем кода в этом примере не очень велик, но сцена в реальном проекте определенно не так проста, несколько случаев переключения не так просто поддерживать, и если добавляется еще один фрукт, вы должны продолжать добавлять слой кейс...赶紧优化Легко думать о режиме стратегии (простое понимание - это полиморфизм), у фруктов есть действие, но каждый фрукт съедается по-разному.

Оптимизация с помощью шаблонов стратегии

Fruit.java

public interface Fruit {
    void eat();
}

Apple.java

public class Apple implements Fruit {
    @Override
    public void eat() {
        System.out.println("是苹果,可以直接吃");
    }
}

Banana.java

public class Banana implements Fruit {
    @Override
    public void eat() {
        System.out.println("吃香蕉了,需要先剥下皮");
    }
}

Watermelon.java

public class Watermelon implements Fruit {
    @Override
    public void eat() {
        System.out.println("吃西瓜了,但是还得弄把水果刀切一下先");
    }
}

Однако обнаружено, что даже при использовании режима стратегии невозможно избежать суждения о типе. EatFruit.java

public class EatFruit {
    private static final String APPLE = "apple";
    private static final String BANANA = "banana";
    private static final String WATERMELON = "watermelon";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //选择的水果种类
        String fruitType = scanner.nextLine();
        Fruit fruit = null;

        switch (fruitType) {
            case APPLE:
                fruit = new Apple();
                break;
            case BANANA:
                fruit = new Banana();
                break;
            case WATERMELON:
                fruit = new Watermelon();
                break;
        }

        fruit.eat();
    }
}

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

Использовать заводской шаблон

Поместите суждение о типе в фабричный класс Фабричный шаблон: логика создания не предоставляется клиенту при создании объекта, а на вновь созданный объект указывают с помощью общего интерфейса, где общий интерфейс — Fruit. Грубо говоря, фабричный паттерн заключается в том, чтобы написать логику создания однотипных объектов в методе FruitFactory.java

public class FruitFactory {
    public static Fruit getFruit(String fruitType) {
        if ("apple".equals(fruitType)) {
            return new Apple();
        }

        if ("banana".equals(fruitType)) {
            return new Banana();
        }

        return new Watermelon();
    }
}

EatFruit .java

public class EatFruit {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //选择的水果种类
        String fruitType = scanner.nextLine();
        Fruit fruit = FruitFactory.getFruit(fruitType);
        fruit.eat();
    }
}

К настоящему времени бизнес-код в EatFruit ясен. Использование фабричного шаблона имеет хорошую инкапсуляцию.Теперь матери больше не нужно заботиться о процессе создания класса, и даже фактически созданный класс не должен заботиться.Он реализует развязку, а также модификацию и изменение фактического класс не повлияет на бизнес верхнего уровня.
Но в фабричном классе еще много «если», революция еще не удалась, и ее еще нужно оптимизировать.

карта Ультрамен здесь

FruitFactory.java

public class FruitFactory {
    private static Map<String, Fruit> fruitMap = new HashMap<>();

    static {
        fruitMap.put("apple", new Apple());
        fruitMap.put("banana", new Banana());
        fruitMap.put("watermelon", new Watermelon());
    }

    public static Fruit getFruit(String fruitType) {
       return fruitMap.get(fruitType);
    }
}

Используя карту,fruitTypeи<T extend Fruit>Сопоставление один к одному и условное суждение говорят до свидания~, код также очень элегантен Окончательная диаграмма классов структуры проекта:类图.png

==================== Следующий контент был обновлен 2018.11.12================

Некоторые пользователи сети отметили, что вместо карты можно использовать отражение, если передается значение типа класса, можно использовать отражение. Преимущество использования рефлексии в том, что при добавлении множества фруктов код фабричного класса не нужно менять
Заменить карту отражением: FruitFactory2.java

public class FruitFactory2 {
    public static <T extends Fruit> T getFruit(Class<T> fruitClass) throws IllegalAccessException, InstantiationException {
        return fruitClass.newInstance();
    }
}