工厂方法这种设计模式在简单工厂模式上进行了改进,主要解决的是方便增加属于同一类的新的产品。
工厂方法是由四部分组成的:
1、抽象产品(对具体产品进行封装)
2、抽象工厂(对具体工厂进行封装)
3、具体产品
4、具体产品工厂
简单工厂是将实例化对象的工作推迟到一个专门负责创建对象的工厂类中,但是这是在我们预知的情况下可以动态的创建新的产品,所以存在产品类别量的局限性。但是预知的产品类量有限,对于无法预知的类就违背了“对扩展开放,对修改封闭的原则”。
工厂方法是在基类中定义创建对象的一个接口,让子类决定实例化哪个类,让一个类的实例化延迟到子类中进行。
问题:具体工厂类创建工作无法满足我们的需求,创建的工作发生了变化。
解决:哪里变化,封装哪里,因此把具体工厂进行一次封装。
如图所示,Laptop是抽象类对具体类进行一次封装,LaptopFactory是对于该抽象类的抽象工厂对具体工厂进行一次封装
举例:
第一步:创建一个抽象产品
屏蔽了产品的实现细节,也就是说对于客户端来说,由抽象工厂类的抽象工厂方法创建的对象具有相同的外貌。可以由接口或者抽象类来定义
public abstract class Laptop {
private String brand;
public Laptop(String brand){
this.brand = brand;
}
abstract public String getId();
public void getDescription(){
System.out.println("this is a " + brand + "laptop");
}
}
第二步:创建一个抽象工厂
抽象工厂将具体工厂类的实现细节隐藏起来,这样即使具体工厂实现类发生过变化,对外部客户端的调用没有任何影响,这体现了工厂类具有多态性
public abstract class LaptopFactory {
//返回值是抽象产品类型,客户端可以根据具体的创建要求进行请求,
//肯定知道创建的对象是哪个具体产品类对象
abstract Laptop produce();
abstract void aftersaleservice();
}
第三步:创建具体的产品类
具有产品对象的数据和服务
public class AcerLaptop extends Laptop {
private static final String brand = "ACER";
protected static int initId;
public AcerLaptop(){
super(AcerLaptop.brand);
initId = 100;
}
@Override
public String getId() {
return "Acer-- " + (initId++);
}
}
public class DellLaptop extends Laptop {
private static final String brand = "Dell";
protected static int initId;
public DellLaptop() {
super(brand);
initId = 200;
}
@Override
public String getId() {
return "Dell--" + (initId++);
}
}
第四步:根据具体的产品类创建个具体的工厂类、
依赖于具体的产品,每一个产品的实例化方式发生变化都影响具体工厂类生产对象的方式产生影响
public class AcerFactory extends LaptopFactory {
@Override
Laptop produce() {
return new AcerLaptop();
}
@Override
void aftersaleservice() {
System.out.println("欢迎致电Acer售后服务");
}
}
public class DellFactory extends LaptopFactory {
@Override
Laptop produce() {
return new DellLaptop();
}
@Override
void aftersaleservice() {
System.out.println("欢迎致电Dell售后服务");
}
}
测试程序:
public class Main {
//增加一个新的产品只需要增加一个新的工厂继承抽象工厂,和一个该产品的一个实现类
public static void main(String[] args) {
LaptopFactory f1 = new AcerFactory();
Laptop c3 = f1.produce();
Laptop c4 = f1.produce();
c3.getDescription();
System.out.println(c3.getId());
c4.getDescription();
System.out.println(c4.getId());
LaptopFactory f2 = new DellFactory();
Laptop c5 = f2.produce();
Laptop c6 = f2.produce();
c5.getDescription();
c6.getDescription();
System.out.println(c5.getId());
System.out.println(c6.getId());
}
}
测试结果:
Acer-- 100
this is a ACERlaptop
Acer-- 101
this is a Delllaptop
Dell--200
this is a Delllaptop
Dell--201