前言:
目前兄弟们对“创建对象一定会调用构造方法吗为什么”大概比较关切,兄弟们都需要了解一些“创建对象一定会调用构造方法吗为什么”的相关资讯。那么小编也在网络上搜集了一些有关“创建对象一定会调用构造方法吗为什么””的相关资讯,希望姐妹们能喜欢,同学们一起来了解一下吧!基本介绍
生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。生成器模式建议将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中,生成器模式让你能够分步骤创建复杂对象。 生成器不允许其他对象访问正在创建中的产品。
类结构图
类图说明:
生成器(Builder) 接口声明在所有类型生成器中通用的产品构造步骤。具体生成器(Concrete Builder) 提供构造过程的不同实现。具体生成器也可以构造不遵循通用接口的产品。产品(Product) 是最终生成的对象。由不同生成器构造的产品无需属于同一类层次接口或接口。主管(Director) 类定义调用构造步骤的顺序,这样你就可以创建和复用特定的产品配置。客户端(Client) 必须将某个生成器对象与主管类关联。一般情况下,你只需要通过主管类构造函数的参数进行一次性关联即可。此后主管类就能使用生成器对象完成后续所有的构造任务。但在客户端将生成器对象传递给主管类时还有另一种方式。在这种情况下,你在使用主管类生产产品时每次都可以使用不同的生成器。实现方式清晰地定义通用步骤, 确保它们可以制造所有形式的产品。 否则你将无法进一步实施该模式。在基本生成器接口中声明这些步骤。为每个形式的产品创建具体生成器类, 并实现其构造步骤。不要忘记实现获取构造结果对象的方法。 你不能在生成器接口中声明该方法, 因为不同生成器构造的产品可能没有公共接口, 因此你就不知道该方法返回的对象类型。 但是, 如果所有产品都位于单一类层次中, 你就可以安全地在基本接口中添加获取生成对象的方法。考虑创建主管类。 它可以使用同一生成器对象来封装多种构造产品的方式。客户端代码会同时创建生成器和主管对象。 构造开始前, 客户端必须将生成器对象传递给主管对象。 通常情况下, 客户端只需调用主管类构造函数一次即可。 主管类使用生成器对象完成后续所有制造任务。 还有另一种方式, 那就是客户端可以将生成器对象直接传递给主管类的制造方法。只有在所有产品都遵循相同接口的情况下, 构造结果可以直接通过主管类获取。 否则, 客户端应当通过生成器获取构造结果。适用场景使用生成器模式可避免重叠构造函数(telescopic constructor)的出现。
假设你的构造函数中有十个可选参数, 那么调用该函数会非常不方便; 因此, 你需要重载这个构造函数, 新建几个只有较少参数的简化版。 但这些构造函数仍需调用主构造函数, 传递一些默认数值来替代省略掉的参数。
class Pizza { Pizza(int size) { ... } Pizza(int size, boolean cheese) { ... } Pizza(int size, boolean cheese, boolean pepperoni) { ... } // ...}当你希望使用代码创建不同形式的产品 (例如石头或木头房屋)时,可使用生成器模式。
如果你需要创建的各种形式的产品, 它们的制造过程相似且仅有细节上的差异, 此时可使用生成器模式。基本生成器接口中定义了所有可能的制造步骤, 具体生成器将实现这些步骤来制造特定形式的产品。 同时, 主管类将负责管理制造步骤的顺序。
示例代码产品生成器接口:ProductBuilder
public interface ProductBuilder { /** * 创建产品组成部分A */ void createPartA(); /** * 创建产品组成部分B */ void createPartB(); /** * 创建产品组成部分C */ void createPartC(); /** * 获取产品 * @return */ Product getProduct();}具体的生成器实现ConcreteBuilder1
public class ConcreteBuilder1 implements ProductBuilder{ private Product product = new Product(); @Override public void createPartA() { product.addPart("零件A1"); } @Override public void createPartB() { product.addPart("零件B1"); } @Override public void createPartC() { product.addPart("零件C1"); } @Override public Product getProduct() { return this.product; }}ConcreteBuilder2
public class ConcreteBuilder2 implements ProductBuilder{ Product product = new Product(); @Override public void createPartA() { product.addPart("零件A2"); } @Override public void createPartB() { product.addPart("零件B2"); } @Override public void createPartC() { product.addPart("零件C2"); } @Override public Product getProduct() { return this.product; }}具体的产品:Product
public class Product { /**产品零件容器**/ private List<String> partList = new ArrayList<>(); /** * 添加部件 * @param part */ public void addPart(String part) { partList.add(part); } public void show() { for(String part:partList) { System.out.println(part); } }}主管类:ProductBuilderDirector
public class ProductBuilderDirector { private final ProductBuilder builder; public ProductBuilderDirector(ProductBuilder builder) { this.builder = builder; } public Product build() { builder.createPartA(); builder.createPartB(); builder.createPartC(); return builder.getProduct(); }}客户端调用代码:Client
public class Client { public static void main(String[] args) { //构建产品,由A1、B1、C1构成 ProductBuilderDirector builderDirector = new ProductBuilderDirector(new ConcreteBuilder1()); Product product = builderDirector.build(); product.show(); System.out.println("-----------------------------------------"); //构建产品,由A2、B2、C2构成 builderDirector = new ProductBuilderDirector(new ConcreteBuilder2()); product = builderDirector.build(); product.show(); }}
标签: #创建对象一定会调用构造方法吗为什么