一、描述
抽象工厂模式是在工厂方法的模式上进一步抽象而来,如果说工厂方法模式是对一个产品结构的创建而言的话,那么抽象工厂模式则是针对多个产品结构而言的,它被用来一次创建多个不同的产品对象。
我们要创建一个摩托车轮胎和摩托车把手,又要创建一个自行车轮胎和自行车把手,如果我们使用工厂方法模式的话我们需要四个类:创建摩托车轮胎的工厂类,创建摩托车把手的工厂类,创建自行车轮胎的工厂类和创建自行车把手的工厂类,但是如果我们使用抽象工厂方法的话,我们需要创建两个工厂类:创建摩托车轮胎和把手的工厂类,创建自行车轮胎和把手的工厂类,也就是将工厂方法进一步抽象,所有摩托车产品归为一类,所有自行车产品归为一类。如果还要创建摩托车的车座和自行车的车座,那么我们只要在摩托车类和自行车类中分别加入一个创建车座的方法即可。
抽象工厂模式适用于创建不同产品的多个结构,使用抽象工厂类负责定义创建对象的接口,这一系列对象的创建工作是由有是实现抽象工厂的具体工厂类来具体完成,抽象工厂模式主要由4部分组成:抽象工厂类,实现抽象工厂类的具体工厂类,抽象类和实现抽象类的具体类。
二、抽象工厂模式的优缺点
优点:在抽象方法模式中,客户端不再负责对象的创建工作,而是把这个任务交给了具体的工厂类,从而减轻了客户端的负担,也明确了各个类的职责。在这个模式中同一个产品的多个不同部件放在一个工厂类中,这样客户端的调用就变得非常简单,而且如果要修改或者增加这些部件就只要修改对应的一个工厂类和实现该工厂类的具体子类即可。
缺点:每次有新的部件加入都需要修改抽象工厂类的设计,同时也要修改实现这个抽象工厂类的所有具体工厂类,需要额外编码增加了代码量。如果每个抽象工厂类中创建的产品数量非常大,在客户端组装各个具体工厂创建的对象的时候就会很复杂,导致客户端代码非常庞大。
三、源代码
总述:对于上一篇博文中采用工厂方法模式编写的薪资计算系统代码,我此次采用抽象工厂的模式,并且我们不仅要计算薪资还要计算社保,也就是有一个抽象工厂类,该类中有两个抽象方法,分别计算薪资和社保,然后有两个分公司类工厂类用于创建自己公司的薪资和社保对象。
1、抽象工厂类
package tong.day5_1.abstractFactory; /** *抽象的工厂接口,在这个接口中定义了一个两个抽象方法,分别创建薪资类对象和社保类对象,由实现该接口的具体类重写该方法,分别创建自己类的对象 * @author tong * */ public interface AbstractFactory { //抽象方法,用于创建各种类的对象 public abstract Salary createSalary(); public abstract Insurance createInsurance(); }
2、具体工厂类
package tong.day5_1.abstractFactory; public class GuangdongFactory implements AbstractFactory { @Override public Salary createSalary() { return new GuangdongSalary(); } @Override public Insurance createInsurance() { return new GuangdongInsurance(); } }
package tong.day5_1.abstractFactory; /** * 具体工厂类实现抽象工厂中的所有方法,并返回该类的薪资对象和社保对象 * @author Administrator * */ public class ZhejiangFactory implements AbstractFactory { @Override public Salary createSalary() { return new ZhejiangSalary(); } @Override public Insurance createInsurance() { return new ZhejiangInsurance(); } }
3、抽象薪资类
package tong.day5_1.abstractFactory; /** * 定义一个薪资接口,所有公司的具体薪资计算都实现这个接口,并重写计算薪资的方法computeSalary() * @author tong * */ public interface Salary { public void computeSalary(); }
4、两个公司的具体薪资类
package tong.day5_1.abstractFactory; /** * 广东分公司的薪资计算类实现了Salary接口,并重写了该接口中的计算薪资的方法computeSalary() * @author tong * */ public class GuangdongSalary implements Salary { @Override public void computeSalary() { System.out.println("广东分公司薪资计算"); } }
package tong.day5_1.abstractFactory; /** * 浙江分公司的薪资计算类实现了Salary接口,并重写了该接口中的计算薪资的方法computeSalary() * @author tong * */ public class ZhejiangSalary implements Salary { @Override public void computeSalary() { System.out.println("浙江分公司薪资计算"); } }
5、抽象社保类
package tong.day5_1.abstractFactory; /** * 抽象社保类 * @author tong * */ public interface Insurance { public abstract void computeInsurance(); }
6、两个子公司的具体社保类
package tong.day5_1.abstractFactory; public class GuangdongInsurance implements Insurance { @Override public void computeInsurance() { System.out.println("广东分公司社会保险计算"); } }
package tong.day5_1.abstractFactory; public class ZhejiangInsurance implements Insurance { @Override public void computeInsurance() { System.out.println("浙江分公司社会保险计算"); } }
7、客户端调用
package tong.day5_1.abstractFactory; public class Client { public static void main(String[] args) { //创建抽象工厂类,使用多态,首先创建浙江分公司的工厂类对象 AbstractFactory factory = new ZhejiangFactory(); //使用浙江分公司的工厂类创建该公司的薪资和社保对象 Salary salary = factory.createSalary(); Insurance insurance = factory.createInsurance(); //使用创建出来的薪资和社保对象分别调用计算薪资和计算社保的具体方法 salary.computeSalary(); insurance.computeInsurance(); System.out.println("----------------"); //创建抽象工厂类,使用多态,创建广东分公司的工厂类对象 factory = new GuangdongFactory(); //使用广东分公司的工厂类创建该公司的薪资和社保对象 salary = factory.createSalary(); insurance = factory.createInsurance(); //使用创建出来的薪资和社保对象分别调用计算薪资和计算社保的具体方法 salary.computeSalary(); insurance.computeInsurance(); } }
三、运行结果