工厂模式是常用的实例化对象的方法,可以用工厂方法代替new操作。我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。在实际使用中,传入对应的参数即可。
工厂模式可以分为三类:简单工厂模式、工厂方法模式和抽象工厂模式。
一、简单工厂模式
首先,我们创建一个接口Fruit,接口中一个抽象方法,用来打印水果的颜色:
public interface Fruit {
void color();
}
之后可以用创建两个实体类,Apple类和Banana类实现工厂接口:
public class Apple implements Fruit{
@Override
public void color() {
System.out.println("color is red");
}
}
public class Banana implements Fruit{
@Override
public void color() {
System.out.println("color is yellow");
}
}
创建一个工厂类,根据不同的参数,new不同的对象:
public class FruitFactory {
public Fruit getFruit(String name) {
Fruit fruit = null;
if (name.equals("banana")) {
return new Banana();
} else if (name.equals("Apple")) {
return new Apple();
}
return null;
}
}
使用该工厂,传入不同的参数获取不同的对象:
public class Test {
public static void main(String[] args) {
FruitFactory factory = new FruitFactory();
Fruit apple = factory.getFruit("apple");
Fruit banana = factory.getFruit("banana");
apple.color();
banana.color();
}
}
简单工厂方法的缺点是每增加一个水果,就要在工厂中增加一个类,适合用于类比较少的情况。
二、工厂方法模式
工厂方法模式对简单工厂模式进一步改进,可以在不修改原有代码的情况下引进新的水果,符合开闭原则。增加一个抽象工厂:
public interface FruitFactory {
Fruit getFruit();
}
针对苹果和香蕉,分别增加两个两个工厂类实现这个工厂接口:
public class AppleFactory implements FruitFactory{
@Override
public Fruit getFruit() {
return new Apple();
}
}
public class BananaFactory implements FruitFactory{
@Override
public Fruit getFruit() {
return new Banana();
}
}
调用具体工厂获取具体的水果:
public static void main(String args[]) {
FruitFactory appleFactory = new AppleFactory();
FruitFactory bananaFactory = new BananaFactory();
Fruit apple = appleFactory.getFruit();
Fruit banana = bananaFactory.getFruit();
apple.color();
banana.color();
}
工厂方法模式的缺点是一种具体工厂只能生产一种具体的类,如果类的种类过多,会造成代码过于复杂。
三、抽象工厂模式
抽象工厂模式,创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。这种模式将多个产品合并成一个产品族。再通过产品族下面的工厂去获取具体的某一类产品。
原有的水果接口保持不变,创建蔬菜接口:
public interface Vegetables {
void getShape();
}
创建两个实体类Cucumber和Tomato,实现蔬菜接口
public class Cucumber implements Vegetables{
@Override
public void getShape() {
System.out.println("strip");
}
}
public class Tomato implements Vegetables {
@Override
public void getShape() {
System.out.println("globular");
}
}
创建抽象工厂FoodFactory,用来获取工厂:
public interface FoodFactory {
Fruit getFruit(String fruit);
Vegetables getVegetables(String vegetables);
}
创建实现了抽象工厂FoodFactory的具体工厂类,基于给定的信息生成对象:
public class FruitFactory implements FoodFactory{
@Override
public Fruit getFruit(String fruit) {
if (fruit.equals("apple")) {
return new Apple();
} else if (fruit.equals("banana")) {
return new Banana();
}
return null;
}
@Override
public Vegetables getVegetables(String vegetables) {
return null;
}
}
public class VegetablesFactory implements FoodFactory {
@Override
public Fruit getFruit(String fruit) {
return null;
}
@Override
public Vegetables getVegetables(String vegetables) {
if (vegetables.equals("cucumber")) {
return new Cucumber();
} else if (vegetables.equals("tomato")) {
return new Tomato();
}
return null;
}
}
创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂:
public class FactoryProduce {
public static FoodFactory getFactory(String choice) {
if (choice.equals("fruit")) {
return new FruitFactory();
} else if (choice.equals("vegetables")) {
return new VegetablesFactory();
}
return null;
}
}
先获取具体的工厂,再通过工厂获取具体的类:
public static void main(String[] args) {
FoodFactory fruitFactory = FactoryProduce.getFactory("fruit");
Fruit fruit = fruitFactory.getFruit("apple");
fruit.color();
FoodFactory vegetablesFactory = FactoryProduce.getFactory("vegetables");
Vegetables vegetables = vegetablesFactory.getVegetables("tomato");
vegetables.shape();
}