一、描述
创建者模式单独利用一个创建者类来创建对象并组建对象之间的关系,以简化客户端调用的复杂性。相对于抽象方法模式来说,创建者模式增加了一个单独的用于组装对象和对象之间关系的创建者类,由该类来负责对象的组装,以此来更加清晰地划分各个类的职责。
创建者模式将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示,而且对客户端屏蔽了对象的构建细节,该模式主要由5个部分组成:组装类、抽象创建者类,实现了抽象创建者类的具体创建者类,抽象产品类、实现了抽象产品类的具体产品类。在此可以看出与抽象方法模式相比多了一个组装类。
二、创建者模式的优缺点
优点:在创建者模式中客户端不再负责对象的创建和组装,而是由一个具体的组装类来完成这项功能,将组装的责任交给组装类,客户端只负责对象的调用,从而更加明确了各个类的职责。
缺点:利用创建者模式可以创建出不同类型的产品,但是如果要创建的产品差异非常大就需要编写多个创建者类来实现,这无疑增加了代码的复杂性,而且创建者类只是在构造相关部件的发杂关系上有优势,如果要增加一个部件还是需要改变原有的代码,增加新的模块。
三、源代码
总述:一个公司有计算薪金和社保需求,我们有多个分公司,每个分公司都要计算这两项,现在我们需要创建分公司对象,利用各个对象调用各个公司计算这两项业务的方法来得出结果,我需要以下几个类:抽象工厂类(定义创建对象的接口),两个子公司的具体工厂类(实现了抽象工厂类中创建对象的方法来产生具体的对象),抽象薪资类(定义薪资计算的标准接口),两个子公司的具体薪资类(实现抽象薪资类中计算薪资的方法),抽象社保类(定义社保计算的标准接口),两个子公司的具体社保类(实现抽象社保类中计算社保的方法),组装类(负责对象的创建和兑现直接关系的组装),客户端调用类(用来调用组装类组装对象并调用相应的实现类方法)。
1、抽象工厂类
package tong.day5_1.builder; /** *抽象的工厂接口,在这个接口中定义了一个两个抽象方法,分别创建薪资类对象和社保类对象,由实现该接口的具体类重写该方法,分别创建自己类的对象 * @author tong * */ public interface AbstractFactory { //抽象方法,用于创建各种类的对象 public abstract Salary createSalary(); public abstract Insurance createInsurance(); }
2、具体工厂类
package tong.day5_1.builder; public class GuangdongFactory implements AbstractFactory { @Override public Salary createSalary() { return new GuangdongSalary(); } @Override public Insurance createInsurance() { return new GuangdongInsurance(); } }
package tong.day5_1.builder; /** * 具体工厂类实现抽象工厂中的所有方法,并返回该类的薪资对象和社保对象 * @author tong * */ public class ZhejiangFactory implements AbstractFactory { @Override public Salary createSalary() { return new ZhejiangSalary(); } @Override public Insurance createInsurance() { return new ZhejiangInsurance(); } }
3、抽象薪资类
package tong.day5_1.builder; /** * 定义一个薪资接口,所有公司的具体薪资计算都实现这个接口,并重写计算薪资的方法computeSalary() * @author tong * */ public interface Salary { public void computeSalary(); }
4、具体薪资类
package tong.day5_1.builder; /** * 广东分公司的薪资计算类实现了Salary接口,并重写了该接口中的计算薪资的方法computeSalary() * @author tong * */ public class GuangdongSalary implements Salary { @Override public void computeSalary() { System.out.println("广东分公司薪资计算"); } }
package tong.day5_1.builder; /** * 浙江分公司的薪资计算类实现了Salary接口,并重写了该接口中的计算薪资的方法computeSalary() * @author tong * */ public class ZhejiangSalary implements Salary { @Override public void computeSalary() { System.out.println("浙江分公司薪资计算"); } }
5、抽象社保类
package tong.day5_1.builder; /** * 抽象社保类 * @author tong * */ public interface Insurance { public abstract void computeInsurance(); }
6、具体社保类
package tong.day5_1.builder; public class GuangdongInsurance implements Insurance { @Override public void computeInsurance() { System.out.println("广东分公司社会保险计算"); } }
package tong.day5_1.builder; public class ZhejiangInsurance implements Insurance { @Override public void computeInsurance() { System.out.println("浙江分公司社会保险计算"); } }
6、组装类
package tong.day5_1.builder; /** * 这里使用一个组装类来简化客户端创建对象、初始化对象以及构建对象之间的关系 * @author tong * */ public class Builder { private AbstractFactory abstractFactory; //根据传入的参数确定初始化哪个公司的工厂类对象,这里使用多态,根据传入的参数动态创建相应的对象 public Builder(AbstractFactory abstractFactory) { this.abstractFactory = abstractFactory; } //组装的具体实现方法,调用类中计算薪金和社保的方法 public void moneySum() { Salary salary = abstractFactory.createSalary(); salary.computeSalary(); Insurance insurance = abstractFactory.createInsurance(); insurance.computeInsurance(); } }
7、客户端调用类
package tong.day5_1.builder; /** * 客户端在这里得到了简化,不用再考虑如何组装创建和组装对象,而只需要调用专门的组装类来组装对象 * @author tong * */ public class Client { public static void main(String[] args) { //组装浙江分公司的对象 Builder builder = new Builder(new ZhejiangFactory()); builder.moneySum(); System.out.println("--------------"); //组装广东分公司的对象 builder = new Builder(new GuangdongFactory()); builder.moneySum(); } }
四、运行结果