主要特点
将对象的创建与使用分离”,这样可以降低系统的耦合度。
创建型模式分为以下几种:
⑴单例(Singleton)模式 :某个类只能生成一个实例,该类提供了一个全 局访问点供外部获取该实例,其拓展是有限多例模式。
⑵ 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克 隆出多个和原型类似的新实例。
⑶ 工厂方法(Factory Method)模式:定义一个用于创建产品的接口,由子 类决定生产什么产品。
⑷ 抽象工厂(Abstract Factory)模式:提供一个创建产品族的接口,其每 个子类可以生产一系列相关的产品。
⑸ 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分, 然后根据不同需要分别创建它们,最后构建成该复杂对象。
定义:指将一个复杂对象的构造与它的表示分离,使同样的构建 过程可以创建不同的表示,它是 将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。
优点:
1)各个具体的建造者相互独立的,有利于系统的扩展;
2)客户端不必知道产品内部组成的细节,便于控制细节 风险。
缺点:
1)产品的组成部分必须相同,**这限制了其使用范围;
2)如果产品的内部变化复杂,该模式会增加很多的建造 者类。
建造者模式注重零部件的组装过程,工厂模式更注重零部件的创建过程
1、结构
代码:
1)产品角色:是包含多个组成部件的复杂对象。
class Product {
private String partA;
private String partB;
private String partC;
}
public void setPartA(String partA) {
this.partA = partA; }
public void setPartB(String partB) {
this.partB = partB;
}
public void setPartC(String partC) {
this.partC = partC;
}
public void show(){
//显示产品的特性
}
}
2)抽象建造者:包含创建产品各个子部件的抽象方法。
abstract class Builder {
//创建产品对象
protected Product product=new Product();
public abstract void buildPartA();
public abstract void buildPartB();
public abstract void buildPartC();
//返回产品对象
public Product getResult() {
return product;
}
}
3)具体建造者:实现了抽象建造者接口。
public class ConcreteBuilder extends Builder {
public void buildPartA(){
product.setPartA("建造PartA");
}
public void buildPartB(){
product.setPartA("建造PartB");
}
public void buildPartC(){
product.setPartA("建造PartC");
}
}
4)指挥者:调用建造者中的方法完成复杂对象的创建。
class Director {
private Builder builder;
public Director(Builder builder) {
this.builder=builder;
}
//产品构建与组装方法
public Product construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
return builder.getResult();
} }
5)客户类
public class Client{
public static void main(String[] args) {
// 创建建造者
Builder builder = new ConcreteBuilder();
// 创建指挥者,指挥建造者
Director director = new Director(builder);
// 通过指挥者完成产品的组装
Product product = director.construct();
product.show();
}
}
2、实现
产品:客厅
class Parlour {
private String wall; //墙
private String TV; //电视
private String sofa; //沙发
public void setWall(String wall) {
this.wall = wall;
}
public void setTV(String TV) {
this.TV = TV;
}
public void setSofa(String sofa) {
this.sofa = sofa;
}
public void show()
{
System.out.println("客厅装修展示");
}
}
抽象建造者:装修工人
abstract class Decorator {
//创建产品对象
protected Parlour product=new Parlour();
// 创建子部件的方法
public abstract void buildWall();
public abstract void buildTV();
public abstract void buildSofa();
//返回产品对象
public Parlour getResult() {
return product;
}
}
具体建造者:具体装修工人1
class ConcreteDecorator1 extends Decorator{
public void buildWall() {
product.setWall("w1");
}
public void buildTV() {
product.setTV("TV1");
}
public void buildSofa() {
product.setSofa("sf1");
}
}
具体建造者:具体装修工人2
class ConcreteDecorator2 extends Decorator{
public void buildWall() {
product.setWall("w2");
}
public void buildTV() {
product.setTV("TV2");
}
public void buildSofa() {
product.setSofa("sf2");
}
}
指挥者:项目经理
class ProjectManager {
private Decorator builder;
public ProjectManager(Decorator builder) {
this.builder=builder;
}
//产品构建与组装方法
public Parlour decorate() {
builder.buildWall();
builder.buildTV();
builder.buildSofa();
return builder.getResult();
}
}
confg.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
// 具体装修师2
<className>ConcreteDecorator2</className>
</config>
ReadXML:该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
class ReadXML{
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getObject() {
try {
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
// 对读取配置文件路径
doc = builder.parse(new File("src/chapter03/factoryMethod/config.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild(); // classNode =CattleFarm
String cName = "chapter03.factoryMethod." + classNode.getNodeValue();
// cName : chapter03.factoryMethod.CattleFarm
//通过类名生成实例对象并将其返回
Class<?> c = Class.forName(cName);
Object obj = c.newInstance();
return obj; // return new CattleFarm();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
测试类:
public class ParlourDecorator {
public static void main(String[] args) {
try
{
// 抽象建造者:装修工人
Decorator d;
// 获取配置文件中的具体建造者:具体装修工人
d=(Decorator) ReadXML.getObject();
// 创建指挥者
ProjectManager m = new ProjectManager(d);
// 通过指挥者完成产品的组装
Parlour p = m.decorate();
p.show();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
建造者模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定.
创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
产品的构建过程和最终的表示是独立的。
建造者模式在应用过程中可以根据需要改变,如果创建的产品种类只有一种,只需要一个具体的建造者,这时可以省略掉抽象建造者,甚至可以省略掉指导者角色