设计模式之工厂方法模式和抽象工厂模式
工厂模式一共有3类:简单工厂(静态工厂)、工厂方法、抽象工厂。
任何可以产生对象的方法或类,都可以称之为工厂单例也是一种工厂。 为什么有了new之后,还要有工厂?
- 灵活控制生产过程;
- 权限、修饰、日志...
工厂方法是在产品纬度进行扩展,抽象工厂是在产品一族进行扩展。
工厂方法(FactoryMethod), 抽象工厂(AbstractFactory)。
简单工厂模式
简单工厂不算是一个真正的设计模式,而更像是一种我们的编程习惯,但是在平时编码中这不失为一个简单的方法,可以将客户程序从具体类解耦。
介绍:工厂类拥有一个工厂方法(create),接受了一个参数,通过不同的参数实例化不同的产品类。
public class AnimalFactory {
//简单工厂设计模式(负担太重、不符合开闭原则)
public static Animal createAnimal(String name) {
if ("cat".equals(name)) {
return new Cat();
} else if ("dog".equals(name)) {
return new Dog();
} else if ("cow".equals(name)) {
return new Dog();
} else {
return null;
}
}
}
工厂方法
定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类。
// 抽象出来的动物工厂----它只负责生产一种产品
public abstract class AnimalFactory {
// 工厂方法
public abstract Animal createAnimal();
}
// 具体的工厂实现类
public class CatFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
//具体的工厂实现类
public class DogFactory extends AnimalFactory {
@Override
public Animal createAnimal() {
return new Dog();
}
}
抽象工厂
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
例如,汽车可以分为轿车、SUV、MPV等,也分为奔驰、宝马等。
我们可以将奔驰的所有车看作是一个产品族,而将宝马的所有车看作是另一个产品族。分别对应两个工厂,一个是奔驰的工厂,另一个是宝马的工厂。
与工厂方法不同,奔驰的工厂不只是生产具体的某一个产品,而是一族产品(奔驰轿车、奔驰SUV、奔驰MPV)。“抽象工厂”的“抽象”指的是就是这个意思。
即相比于工厂方法,抽象工厂定义了一系列的产品,而不是一个产品。
上边的工厂方法模式是一种极端情况的抽象工厂模式(即只生产一种产品的抽象工厂模式),而抽象工厂模式可以看成是工厂方法模式的一种推广。
public abstract class AbastractFactory {
abstract Food createFood();
abstract Vehicle createVehicle();
abstract Weapon createWeapon();
}
public class MagicFactory extends AbastractFactory {
@Override
Food createFood() {
return new MushRoom();
}
@Override
Vehicle createVehicle() {
return new Broom();
}
@Override
Weapon createWeapon() {
return new MagicStick();
}
}
public class ModernFactory extends AbastractFactory {
@Override
Food createFood() {
return new Bread();
}
@Override
Vehicle createVehicle() {
return new Car();
}
@Override
Weapon createWeapon() {
return new AK47();
}
}
public class Main {
public static void main(String[] args) {
AbastractFactory f = new ModernFactory();
Vehicle c = f.createVehicle();
c.go();
Weapon w = f.createWeapon();
w.shoot();
Food b = f.createFood();
b.printName();
}
}