平时我们都是自己new对象,需要知道创建对象的具体过程,但是工厂模式为我们提供了一种便利。我们不需要知道创建对象的具体流程,而只需要告诉工厂,我需要一个对象,工厂就为我们创建一个对象,不需要关注创建对象的逻辑。这有利于我们简化复杂对象的创建。
简单工厂模式是创建型模式,但他不是GOF23种模式中的一种。
角色:工厂,抽象产品,具体产品。
一天下午,我来到了一家咖啡馆,用手机点了一杯摩卡咖啡。过了一会儿,服务员就把热乎乎的咖啡就到了我的面前。在这个过程中我只是点了点手机,通知到了商家我需要一杯摩卡,摩卡就被做了出来。我不需要知道摩卡是怎么做出来的,我只负责喝。下一次我再来的时候,我可能想要一杯卡布奇洛,我也只负责喝和付钱。在这里面,商家就对应着工厂,抽象产品就对应着咖啡,具体产品就对应着卡布奇洛或者摩卡。
商家(咖啡工厂)生产咖啡
public class CoffeeFactory { //传入具体咖啡种类的名字,创建对应的对象。 public Coffee createCoffee(String type){ if ("Cappuccino".equals(type)) { return new Cappuccino(); }else if ("Mocha".equals(type)) { return new Mocha(); } else { return null; } } } public interface Coffee { } public class Cappuccino implements Coffee { } public class Mocha implements Coffee { } public class SimpleFactoryTest { public static void main(String[] args) { CoffeeFactory coffeeFactory = new CoffeeFactory(); Coffee cappuccino = coffeeFactory.createCoffee("Cappuccino"); } }但是其实我们很容易看到这种模式的缺点,我们需要传入参数,也就是说我们并不能对工厂内部创建对象的逻辑一无所知。而且如果商家(咖啡工厂)后来学会了做其他种类咖啡的技术,那么我们就必须要修改商家(咖啡工厂)的代码。这违背了开闭原则。所以让我们看看工厂方法模式。
工厂方法模式是创建型模式,属于GOF23种设计模式。
角色:抽象工厂,具体工厂,抽象产品,具体产品。
简单工厂模式中的工厂可以生产多种具体产品,只要它是咖啡就行。这种方式的缺点是我们需要对工厂创建产品的方法有一定的了解,至少要知道怎么样才能创建一个我们需要的产品。而在工厂方法模式中,有一个抽象工厂,声明创建产品的方法,而不同的具体工厂都只生产一种具体的类,这个时候,我们就不需要去关心方法中对象的创建逻辑了。就像我去了一家只卖摩卡咖啡的咖啡厅(具体工厂),我只能点摩卡咖啡(具体产品),没得选。其实这样也免得我选择困难症犯了。
抽象工厂
public interface AbstractFactory { Coffee createCoffee(); }具体工厂
public class MochaFactory implements AbstractFactory { @Override public Mocha createCoffee() { return new Mocha(); } } public class CappuccinoFactory implements AbstractFactory { @Override public Cappuccino createCoffee() { return new Cappuccino(); } }抽象产品
public interface Coffee { }具体产品
public class Cappuccino implements Coffee { } public class Mocha implements Coffee { }测试类
public class FactoryMethodTest { public static void main(String[] args) { MochaFactory mochaFactory = new MochaFactory(); Mocha mocha = mochaFactory.createCoffee(); CappuccinoFactory cappuccinoFactory = new CappuccinoFactory(); Cappuccino cappuccino = cappuccinoFactory.createCoffee(); } }如果以后有了新的产品,我们只需要创建对应的产品类和工厂类就可以了,不需要再去修改原来的代码。但是这样容易造成类的数量过多。
工厂方法模式是创建型模式,属于GOF23种设计模式。
角色:抽象工厂,具体工厂,抽象产品,具体产品。
我们买咖啡的时候不免要选择品牌,如雀巢、星巴克等,每一个品牌都能制作摩卡咖啡和卡布奇洛。但是不同品牌的制作方式和口味是不一样的。所以制作摩卡和卡布奇洛可以定义为抽象工厂的抽象方法,每个品牌的制作流程的具体实现就是具体工厂的具体方法,而具体产品就是具体工厂生产出来的不同品牌的不同类别的产品,比如说星巴克的卡布奇洛,雀巢的摩卡等。
只需要注意NestleFactory实现了CoffeeFactory接口,并且生产NestleMocha和NestleCappuccino。
StarbucksFactory实现了CoffeeFactory接口,并且生产StarbucksCappuccino和StarbucksMocha。
抽象工厂
public interface CoffeeFactory { Mocha createMocha(); Cappuccino createCappuccino(); }具体工厂
public class NestleFactory implements CoffeeFactory { @Override public Mocha createMocha() { return new NestleMocha(); } @Override public Cappuccino createCappuccino() { return new NestleCappuccino(); } } public class StarbucksFactory implements CoffeeFactory { @Override public Mocha createMocha() { return new StarbucksMocha(); } @Override public Cappuccino createCappuccino() { return new StarbucksCappuccino(); } }抽象产品
public interface Mocha { } public interface Cappuccino{ }具体产品
public class NestleCappuccino implements Cappuccino { } public class StarbucksCappuccino implements Cappuccino { } public class NestleMocha implements Mocha { } public class StarbucksMocha implements Mocha { }测试类
public class AbstractFactoryTest { public static void main(String[] args) { //生产雀巢的卡布奇洛和摩卡 NestleFactory nestleFactory = new NestleFactory(); Cappuccino nestleCappuccino = nestleFactory.createCappuccino(); Mocha nestleMocha = nestleFactory.createMocha(); //生产星巴克的卡布奇洛和摩卡 StarbucksFactory starbucksFactory = new StarbucksFactory(); Cappuccino starbucksCappuccino = starbucksFactory.createCappuccino(); Mocha starbucksMocha = starbucksFactory.createMocha(); } }总结:
简单工厂模式:一个工厂生成多种产品,但是需要在工厂的方法中加入判断逻辑。
工厂方法模式:多个工厂,每个工厂生产一种具体产品。
抽象工厂模式:多个工厂,每个工厂生成多种具体产品。
