文章同步发放到简书
工厂模式
工厂模式主要是为创建对象提供接口,将创建对象的过程隔离起来,实现了创建者与调用者的分离,提高了程序的灵活性。
核心本质:
- 实例化对象,用工厂方法代替new操作。
- 将选择实现类、创建对象统一管理和控制,从而将调用者跟我们实现类解耦。
工厂模式分类:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
一、简单工厂模式
又称为静态工厂方法模式用来生产同一等级结构中的任意产品,通过 建立一个工厂(一个函数或一个类方法)来制造新的对象。
模式组成结构:
抽象产品: 它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
具体产品: 工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
- 工厂类: 这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
示例代码
抽象产品:
public interface Car {
void run();
}
具体产品:
public class Audi implements Car {
@Override
public void run() {
System.out.println("奥迪车!");
}
}
public class Byd implements Car {
@Override
public void run() {
System.out.println("比亚迪车!");
}
}
工厂类:
public class SimpleFactory {
public Car createCar(String type ){
if("奥迪".equals(type)){
return new Audi();
}else if("比亚迪".equals(type)){
return new Byd();
}else{
return null ;
}
}
}
客户类:
public class Customer {
public static void main(String[] args ) {
SimpleFactory factory = new SimpleFactory();
Car car1 =factory.createCar("奥迪");
Car car2 =factory.createCar("比亚迪");
}
}
以上便是简单工厂模式, 但是工厂部分好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createCar(String type)方法需要新增case),这显然是违背开闭原则的 。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类或者上帝类。
于是工厂方法模式出现了。 工厂类定义成了接口,而每新增的车种类型,就增加该车种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。
二、工厂方法模式
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。
模式组成结构:
- 抽象产品: 它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
- 具体产品: 工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
- 抽象工厂: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
- 具体工厂: 它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
示例代码
抽象产品与具体产品类代码与上面相同。
抽象工厂:
public interface CarFactory {
Car createCar();
}
具体工厂:
public class AudiFactory implements CarFactory {
@Override
public Car createCar() {
return new Audi();
}
}
public class BydFactory implements CarFactory {
@Override
public Car createCar() {
return new Byd();
}
}
客户类:
public class Customer {
public static void main(String[] args) {
Car c1 = new AudiFactory().createCar();
Car c2 = new BydFactory().createCar();
}
}
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代 码。可以看出工厂角色的结构也是符合开闭原则的!
三、简单工厂模式VS工厂方法模式
1 ) 结构复杂度:简单工厂模式优胜。
2)代码复杂度:简单工厂模式占优。
3)管理难度: 工厂方法模式的核心是一个抽象工厂类,而不像简单工厂模式, 把核心放在一个实类上。可拓展性更好,易于管理。
总结:根据设计理论建议用工厂方法模式,但是实际上,我们一般都是使用简单工厂模式!
四、抽象工厂模式
在抽象工厂模式中,抽象产品 (AbstractProduct) 可能是一个或多个,从而构成一个或多个产品族(Product Family)。如构成一辆车需要有发动机,座椅,轮胎等配件,而每个配件又有多种(如发动机有A,B不同型号),那么该抽象产品构成一个产品族。
当每个抽象产品都有多于一个的具体子类的时候(发动机有型号A和B两种,座椅也有型号A和B两种),工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品(产品轮胎有两个具体产品轮胎A和轮胎B)。抽象工厂模式提供两个具体工厂角色(A型汽车系列工厂和B型系列工厂),分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。
示例代码
不同的抽象产品族:
/**
* 发动机接口及具体子类
*/
public interface Engine {
void run();
}
class EngineA implements Engine{
@Override
public void run() {
System.out.println("转的快!");
}
}
class EngineB implements Engine{
@Override
public void run() {
System.out.println("转的慢!");
}
}
/**
* 座椅接口及具体子类
*/
public interface Seat {
void massage();
}
class LuxurySeat implements Seat {
@Override
public void massage() {
System.out.println("可以自动按摩!");
}
}
class LowSeat implements Seat {
@Override
public void massage() {
System.out.println("不能按摩!");
}
}
不同的工厂:
//汽车工厂接口
public interface CarFactory {
Engine createEngine();
Seat createSeat();
}
//A类汽车工厂
public class CarFactoryA implements CarFactory {
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Seat createSeat() {
return new SeatA();
}
}
//B类汽车工厂
public class CarFactoryB implements CarFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Seat createSeat() {
return new SeatB();
}
}
客户:
public class Customer {
public static void main(String[] args) {
//得到不同配件构成的汽车
CarFactory factory1 = new CarFactoryA();
Engine e = factory1.createEngine();
Seat s=factory1.createSeat();
CarFactory factory2 = new CarFactoryB();
Engine e1= factory2.createEngine();
Seat s1=factory2.createSeat();
}
}
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。