工厂模式
现实生活中有很多的工厂,汽车厂,摩托厂。如果一个商人,想要购买汽车或者摩托,优先考虑的是去工厂商谈,签订购买合同,而不是去考虑生产多少汽车或者摩托,同样对于某些环境下,我们希望对象的创建的具体细节是封装好的,比如汽车的零件采购组装,我们不想去了解,那么直接找到对应的工厂类,对它说我们需要一个**对象,然后工厂新建或者组装出一个对象供我们使用。
工厂模式的定义
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作交到具体子工厂类中,实现创建与使用相分离。
工厂模式的结构
工厂模式由抽象工厂、具体 工厂、抽象产品和具体产品构成。
抽象工厂主要提供了创建产品的接口;具体工厂是实现了抽象工厂中的抽象方法,完成具体产品的创建;抽象产品则定义了产品的规范,相应的特性和功能;具体产品实现了抽象产品定义的内容,由具体工厂来创建。
参考案例:
// 抽象产品:水果
interface Fruit {
void show();
}
// 具体产品:苹果
static class Apple implements Fruit {
@Override
public void show() {
System.out.println("这是一个苹果!");
}
}
// 具体产品:橘子
static class Orange implements Fruit {
@Override
public void show() {
System.out.println("这是一个橘子!");
}
}
// 抽象工厂
interface FruitFactory {
Fruit newFruit();
}
// 苹果工厂
static class AppleFactory implements FruitFactory {
private static AppleFactory instance = new AppleFactory();
public static AppleFactory getInstance() {
return instance;
}
@Override
public Fruit newFruit() {
System.out.println("苹果工厂生产了一个苹果!");
return new Apple();
}
}
// 橘子工厂
static class OrangeFactory implements FruitFactory {
private static OrangeFactory instance = new OrangeFactory();
public static OrangeFactory getInstance() {
return instance;
}
@Override
public Fruit newFruit() {
System.out.println("橘子工厂生产了一个橘子!");
return new Orange();
}
}
// 采购者
static class Purchaser {
public int apple;
public int orange;
public List needBuy;
public Purchaser(int apple, int orange) {
this.apple = apple;
this.orange = orange;
this.needBuy = new ArrayList<>();
}
public void add(Fruit fruit) {
needBuy.add(fruit);
}
public int getFruitSize(String name) {
int size = 0;
for (Fruit fruit : needBuy) {
switch (name) {
case "Apple":
if (fruit instanceof Apple) {
fruit.show();
size++;
}
break;
case "Orange":
if (fruit instanceof Orange) {
fruit.show();
size++;
}
break;
default:
}
}
return size;
}
}
@Test
public void main() {
Purchaser purchaser = new Purchaser(2,3);
for (int i = 0; i < purchaser.apple; i++) {
purchaser.add(AppleFactory.getInstance().newFruit());
}
for (int i = 0; i < purchaser.orange; i++) {
purchaser.add(OrangeFactory.getInstance().newFruit());
}
System.out.println("采购苹果:"+purchaser.getFruitSize("Apple"));
System.out.println("采购橘子:"+purchaser.getFruitSize("Orange"));
}
运行结果:
------------------------------------------------
苹果工厂生产了一个苹果!
苹果工厂生产了一个苹果!
橘子工厂生产了一个橘子!
橘子工厂生产了一个橘子!
橘子工厂生产了一个橘子!
这是一个苹果!
这是一个苹果!
采购苹果:2
这是一个橘子!
这是一个橘子!
这是一个橘子!
采购橘子:3
------------------------------------------------
工厂模式通常用于不关心对象细节,只关心对象的产出的时候。
抽象工厂模式
抽象工厂模式是工厂模式的升级版,工厂方法只生产一个产品,而抽象工厂模式则用于生产多个产品。
抽象工厂模式的结构
抽象工厂也是由抽象工厂、具体工厂、抽象产品和具体产品组成,区别在于抽象工厂不止能生产一件产品。
举个例子:
interface Fruit {
void show();
}
interface IFruitFactory {
Orange newOrange();
Apple newApple();
}
static class Apple implements Fruit {
@Override
public void show() {
System.out.println("这是一个苹果!");
}
}
static class Orange implements Fruit {
@Override
public void show() {
System.out.println("这是一个橘子!");
}
}
static class FruitFactory implements IFruitFactory {
private static FruitFactory instance = new FruitFactory();
public static FruitFactory getInstance() {
return instance;
}
@Override
public Orange newOrange() {
System.out.println("水果工厂生产了一个橘子!");
return new Orange();
}
@Override
public Apple newApple() {
System.out.println("水果工厂生产了一个苹果!");
return new Apple();
}
}
interface Animal {
void show();
}
static class Chicken implements Animal {
@Override
public void show() {
System.out.println("这是一个烧鸡!");
}
}
static class Duck implements Animal {
@Override
public void show() {
System.out.println("这是一个烤鸭!");
}
}
interface IAnimalFactory {
Chicken newChicken();
Duck newDuck();
}
static class AnimalFactory implements IAnimalFactory {
private static AnimalFactory instance = new AnimalFactory();
public static AnimalFactory getInstance() {
return instance;
}
@Override
public Chicken newChicken() {
System.out.println("动物工厂生产了一个烧鸡!");
return new Chicken();
}
@Override
public Duck newDuck() {
System.out.println("动物工厂生产了一个烤鸭!");
return new Duck();
}
}
static class Purchaser {
public int fruit;
public int animal;
public List buyFruit;
public List buyAnimal;
public Purchaser(int fruit, int animal) {
this.fruit = fruit;
this.animal = animal;
this.buyFruit = new ArrayList<>();
this.buyAnimal = new ArrayList<>();
}
public void addFruit(Fruit fruit) {
buyFruit.add(fruit);
}
public void addAnimal(Animal animal) {
buyAnimal.add(animal);
}
}
@Test
public void main() {
Purchaser purchaser = new Purchaser(2,3);
for (int i = 0; i < purchaser.animal; i++) {
purchaser.addAnimal(AnimalFactory.getInstance().newChicken());
purchaser.addAnimal(AnimalFactory.getInstance().newDuck());
}
for (int i = 0; i < purchaser.fruit; i++) {
purchaser.addFruit(FruitFactory.getInstance().newApple());
purchaser.addFruit(FruitFactory.getInstance().newOrange());
}
}
运行结果:
------------------------------------------------
动物工厂生产了一个烧鸡!
动物工厂生产了一个烤鸭!
动物工厂生产了一个烧鸡!
动物工厂生产了一个烤鸭!
动物工厂生产了一个烧鸡!
动物工厂生产了一个烤鸭!
水果工厂生产了一个苹果!
水果工厂生产了一个橘子!
水果工厂生产了一个苹果!
水果工厂生产了一个橘子!
------------------------------------------------
从上面可以看到,工厂不再具体生产某一种产品,它可以生产多个商品,它从苹果工厂变成了水果工厂,相当于采购者不需要单独去找某一个特性的工厂,而是通过水果工厂即刻购买所有类型的水果,采购者不需要关心这些对象是如何生成的,无论是本地种植的还是国外进口的,都能通过同一个水果工厂获取。