工厂设计模式(三种) — 创建型

简介

工厂模式(Factory Design Pattern):也是创建型中常用设计模式;又可细分为三种类型:简单工厂,工厂方法,抽象工厂;工厂顾名思义就是生产产品,在这里是指创建对象;工

简单工厂模式

下面通过动物饲养的例子,实现简单工厂模式;

1,创建一个动物接口:

public interface Animal {//动物抽象

    void eat();//动物的行为
}

2,具体的动物类(具体对象类)

public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头!");
    }
}
public class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼!");
    }
}
public class Sheep implements Animal {
    @Override
    public void eat() {
        System.out.println("羊吃草!");
    }
}

3,创一个饲养厂(工厂),专门饲养(创建对象)各种动物

public class AnimalFactory {
    public static Animal createAnimal(String name) {
        if ("dog".equalsIgnoreCase(name)) {
            return new Dog();
        } else if ("cat".equalsIgnoreCase(name)) {
            return new Cat();
        }else if ("sheep".equalsIgnoreCase(name)) {
            return new Sheep();
        }
        return null;
    }
}

工厂类中创建对象的方法一般都是 create 开头,比如代码中的 createAnimal(),但有的也命名为 getInstance()、reateInstance()、newInstance(),这个我们根据具体的场景和习惯来命名就好。一般方法都是静态的,所以有些还成为静态工厂;

以上就是简单工厂模式;

使用:

public class Demo {

    public static void main(String[] args) {
        Animal dog = AnimalFactory.createAnimal("Dog");
        dog.eat();

        Animal cat = AnimalFactory.createAnimal("cat");
        cat.eat();

        Animal sheep = AnimalFactory.createAnimal("Sheep");
        sheep.eat();
    }
}

总结:简单工厂存在一个问题就是,如果再增加一种动物,那就要增加一个实体类继承Animal接口,然后修改工厂类,这样不太符合开闭原则:对扩展开放,对修改关闭;实际如果不平凡的增加动物(实体类),也没有太多动物,这样的修改也是可以接受的;

工厂方法模式

如果要解决简单工厂缺点,工厂方法就应运而生了,也是简单工厂的升级;具体可以通过多态对工厂类实现可扩展;重构工厂类如下:

public interface IAnimalFactory {

    Animal createAnimal();
}
public class DogAnimalFactory implements IAnimalFactory {
    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}
public class CatAnimalFactory implements IAnimalFactory {
    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}
public class SheepAnimalFactory implements IAnimalFactory {

    @Override
    public Animal createAnimal() {
        return new Sheep();
    }
}

以上就是典型的工厂方法模式实现;把工厂类又抽象了一层;具体动物类创建,就到了工厂接口的具体实现类中;

使用:

public class Demo {
    public static void main(String[] args) {
        IAnimalFactory dagFactory = createAnimal("dog");
        Animal dog = dagFactory.createAnimal();

        IAnimalFactory dagFactory = createAnimal("cat");
        Animal dog = dagFactory.createAnimal();
    }

    public static IAnimalFactory createAnimal(String name) {
        if ("dog".equalsIgnoreCase(name)) {
            return new DogAnimalFactory();
        } else if ("cat".equalsIgnoreCase(name)) {
            return new CatAnimalFactory();
        }else if ("sheep".equalsIgnoreCase(name)) {
            return new SheepAnimalFactory();
        }
        return null;
    }
}

在以上的使用过程中还会发现,createAnimal()方法去掉过多的if-else,还可以创建一个简单工厂方式,去掉过多if-else,也就是工厂的工厂,用来创建工厂类对象;具体实现如下:单例模式实现简单工厂;

class AnimalFactoryMap {
    private static final Map cachedFactories = new HashMap<>();

    static {
        cachedFactories.put("dog", new DogAnimalFactory());
        cachedFactories.put("cat", new CatAnimalFactory());
        cachedFactories.put("sheep", new SheepAnimalFactory());
    }

    public static IAnimalFactory getParserFactory(String type) {
        if (type == null || type.isEmpty()) {
            return null;
        }
        IAnimalFactory animalFactory = cachedFactories.get(type.toLowerCase());
        return animalFactory;
    }
}

简单工厂和工厂方法什么时候用?

当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。而使用简单工厂模式,将所有的创建逻辑都放到一个工厂类中,会导致这个工厂类变得很复杂。

抽象工厂模式

这个不好用以上案例进行解释,以一个工厂,即生产手机有生产电脑为例;如下

手机接口类

public interface Phone {
    void call();
}

手机实体类 

public class HuaweiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("用华为手机打电话!");
    }
}

 

public class XiaoMiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("用小米手机打电话!");
    }
}

 

电脑接口类

public interface Computer {
    void work();
}

电脑实体类

public class MacComputer implements Computer {

    @Override
    public void work() {
        System.out.println("用苹果电脑工作");
    }
}
public class DellComputer implements Computer {

    @Override
    public void work() {
        System.out.println("用戴尔电脑工作");
    }
}

抽象工厂类

 

为Computer和Phone创建接口来获取工厂;

public interface AbstractFactory {

    Computer createComputer(String name);//根据name获取不同品牌的电脑对象;
    Phone createPhone(String name);//根据name获取不同品牌的手机对象;
}

使用:以富士康为例

public class FuShiKangFactory implements AbstractFactory {
    @Override
    public Computer createComputer(String name) {
        if ("mac".equalsIgnoreCase(name)) {
            return new MacComputer();
        } else if ("dell".equalsIgnoreCase(name)) {
            return new DellComputer();
        }
        return null;
    }

    @Override
    public Phone createPhone(String name) {
        if ("huawei".equalsIgnoreCase(name)) {
            return new HuaweiPhone();
        } else if ("xiaomi".equalsIgnoreCase(name)) {
            return new XiaoMiPhone();
        }
        return null;
    }
}

总结:抽象工厂的另一种写法就是把Computer和Phone的实现类都是同一个品牌;这样一个工厂就只生产一个品牌的Phone和Computer

改进:

手机接口类

public interface Phone {
    void call();
}

手机实体类 

public class HuaweiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("用华为手机打电话!");
    }
}

 

public class XiaoMiPhone implements Phone {
    @Override
    public void call() {
        System.out.println("用小米手机打电话!");
    }
}

电脑接口类

public interface Computer {
    void work();
}

电脑实体类

public class HuaWeiComputer implements Computer {

    @Override
    public void work() {
        System.out.println("用华为电脑工作");
    }
}
public class XiaoMiComputer implements Computer {

    @Override
    public void work() {
        System.out.println("用小米电脑工作");
    }
}

抽象工厂类

为Computer和Phone创建接口来获取工厂;

public interface AbstractFactory {

    Computer createComputer();
    Phone createPhone();
}

使用:

小米工厂

public class XiaoMiFactory implements AbstractFactory2 {
    @Override
    public Computer createComputer() {
        return new XiaoMiComputer();
    }

    @Override
    public Phone createPhone() {
        return new XiaoMiPhone();
    }

}

华为工厂

public class HuaWeiFactory implements AbstractFactory2 {
    @Override
    public Computer createComputer() {
        return new HuaweiComputer();
    }

    @Override
    public Phone createPhone() {
        return new HuaweiPhone();
    }

}

总结:工厂模式可以应用到自定义依赖注入框架种,通过读取配置文件,经过工厂模式创建出对象;工厂模式是用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。

你可能感兴趣的:(设计模式)