- 创建型模式关注对象的创建过程
- 将对象的创建和使用分离(组件封装)
工具类
config.xml
<?xml version="1.0"?>
<config>
<chartType>histogram<chartType>
</config>
XMLUtil
public class XMLUtil {
public static Object getBean() {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src//firstexp//config.xml"));
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild();
String cName = classNode.getNodeValue();
Class c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
}
catch (Exception e){
e.printStackTrace();
return null;
}
}
}
// 使用
IAutoFactory factory;
factory = (IAutoFactory) XMLUtil.getBean();
factory.createMed().ignition();
factory.createMed().startup();
简单工厂模式
概述
- 通俗版
一套图标库里有不同类型的图表,根据不同的参数获得不同的类型的图表 - 标准版
- 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
- 类创建型模式,静态工厂方法
结构
- Factory(工厂角色):工厂类,;提供了静态方法factoryMethod(),返回类型为抽象产品类型Product
- Product(产品角色): 父类,图表库
- ConcreteProduct(具体产品角色):不同类型的图表
- 结构图
模板
步骤1:抽象产品类
抽象产品类有以下几个重点:
- 产品类重构,根据实际情况设计一个产品层次结构
- 将所有公共代码 =>抽象产品类
- 声明一些抽象方法,共不同的具体产品实现
public abstract class Product {
// 所有产品类的公共业务方法
public void methodSame() {
}
// 声明抽象业务方法
public abstract void methodDiff();
}
步骤2:在具体产品类中实现抽象产品类中声明的抽象业务方法
public class ProductA extends Product {
// 实现业务方法
public void methodDiff(){
}
}
** 步骤3:简单工厂实现**
public class SimpleFactory {
public static Product getProduct(String arg) {
Product product = null;
if (arg.equalsIgnoreCase("A")){
product = new ProductA();
// 初始化设置A
}
else if (arg.equalsIgnoreCase("B")){
product = new ProductB();
// 初始化设置B
}
return product
}
}
** 步骤4:具体使用**
main() {
Product product;
product = Factory.getProduct("A");
product.methodSame();
product.methodDiff();
}
优缺点
优点:
- 客户无需知道所创建的具体产品类的类名,只需要知道对应的参数
- 通过引入配置文件,可以在不修改任何客户端的代码情况下,更换和新增具体产品类
缺点:
- 由于工厂集中了所有产品的创建逻辑,一旦失效,则系统瘫痪
- 增加系统中类的个数且增加了系统的复杂度和理解读
- 系统扩展困难
适用环境:
- 负责创建的对象较少
- 客户端只知道传入工厂类的参数。
工厂方法模式
工厂方法模式解决了,简单工厂模式中 新增具体产品时需要改动工厂方法的缺点。
其解决方法为:不再提供一个统一工厂去创建所有产品,而是给不同产品建立各自的工厂
结构
- Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的父类
- ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品直接一一对应
- Factory(抽象工厂)
- ConcreteFactory(具体工厂)
模板
步骤1:建立产品类
同简单工厂
步骤2:建立抽象工厂类
public interface Factory {
public Product factoryMethod();
}
步骤3:具体工厂
public class ConcreteFactory implements Factory{
public Product factoryMethod(){
return new ContreteProduct();
}
}
步骤四:客户端
Factory factory;
facotry = new ContreteFactory();
Product product;
product = factory.factoryMethod();
实例
系统日志记录:有文件和数据两种形式
实例结构图
代码步骤
若需要增加并使用新的日志记录器,只需要对应增加一个新的具体工厂,然后再客户端代码中修改具体工厂的类名。
步骤1:Logger:日志记录器接口,充当抽象产品角色
public interface Logger {
public void writeLog();
}
步骤2:DatabaseLogger/FileLogger: 数据库/文件日志记录器,充当具体产品角色
public class DatabaseLogger implements Logger {
public void writeLog(){
System.out.println("数据库日志记录")
}
}
步骤3: LoggerFactory: 日志记录器工程接口,充当抽象工厂角色
public interface LoggerFactory() {
public Logger createLogger(); // 抽象工厂方法
}
步骤4: DatabaseLoggerFactory: 数据库/文件日志记录器工厂类,充当具体工厂角色
public class DatabaseLoggerFactory implements LoggerFactory {
public Logger createLogger () {
// 连接数据库,代码省略
// 创建数据库日志记录器对象
Logger logger = new DatabaseLogger();
return logger;
}
}
步骤5: 客户端测试
public Class client {
public static void main(String args[]){
LoggerFactory factory;
Logger logger;
factory = new FileLoggerFactory();
logger = factory.createLogger();
logger.writeLog()
}
}
工厂方法的隐藏
工厂方法隐藏的结构图如图所示
LoggerFactory代码
public abstract class LoggerFactory {
// 在工厂类中直接调用日志记录器类的业务方法writeLog()
public void writeLog(){
Logger logger = this.createLogger();
logger.writeLog();
}
public abstract Logger createLogger();
}
// 客户端
LoggerFactory factory;
factory = (LoggerFactory) XMLUtil.getBean()
factory.writeLog()
抽象工厂
工厂方法中每个具体工厂只有一个产品,可能会导致系统中存在大量工厂
抽象工厂将一类产品形成一个产品族,不同工厂即为不同等级
结构
- 抽象工厂:声明了一组用于创建一族产品的方法,每个方法对应一种产品
- 具体工厂:实现了在抽象工厂中声明的创建产品的方法
- 抽象产品:为每种产品提供接口
- 具体产品
模板
步骤1:抽象工厂
public interface AbstractFactory{
public AbstractProductA createProductA();
public AbstractProductB createProductB();
}
步骤2: 具体工厂
public class ConCreteFactory extends AbstractFactory {
// 工厂方法一
public AbstractproductA createProductA(){
return new ConcreteProductA();
}
}
实例
两种不同的应用主题,每种主题主要更改按钮、文本框、组合框的样式
结构图如下
具体步骤:
步骤1: Button/Text/Field接口,只举一个
public interface Button {
public void display();
}
步骤2: Spring/SummerButton,两种不同的分隔,也是只举例一个
public class SpringButton implements Button {
public void display(){....}
}
public class SummerButton implements Button {
public void display(){....}
}
步骤3: 抽象工厂
public interface SkinFactory {
public Button createButton();
public Text createText();
...
}
步骤4: 具体工厂
public SpringSkinFactory implements SkinFactory {
public Button createButton(){
return new SpringButton();
};
public Text createText(){....};
...
}
建造者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
建造者模式是一种对象创建型模式,它将客户端与包含多个部件的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成与装配形式,只需要知道所需建造者的类型即可。
结构图
- Builder(抽象建造者) 在该接口中一般声明两类方法,一类是buildPartX(),用于创建复杂对象的各个部件;另一类是getResult(),用于返回复杂对象。既可以是接口,也可以是类
- ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确所创建的复杂对象,还可以提供一个方法返回创建好的复杂产品对象
- Product(产品): 它是被构建的对象,包含多个组成部件,具体建造者创建改产品的内部表示并定义它的装配过程
- **dIrector(指挥者):**指挥者又称导演类,负责安排复杂对象的构建次序。
客户端一般只与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象,然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中
模板
一个典型的复杂对象类的示例代码如下:
public class Product {
private String partA;// 定义部件,可以是任意类型
private String partB;
// partAde Getter和Setter方法
}
在抽象建造者类中定义了产品的创建方法和返回方法。
在抽象类Builder中声明了一系列buildPartX()方法,用于创建复杂产品的各个部件,具体建造过程在ConcreteBuilder中实现。
public abstract class Builder {
// 创建产品对象
protected Product product = new Product();
//部件
public abstract void buildPartA();
//返回产品对象
public Product getResult(){
return product;
}
}
在ConcreteBuilder中实现了这些buildPartX()方法,通过调用Product的setPartX()方法,可以给产品对象成员赋值
public class ConcreteBuilder extends Builder {
public void buildPartA(){
product.setPartA("A")
}
.....
}
Director类,用于控制产品的创建过程
指挥者类中可以注入一个抽象建造者类型的对象,它提供了一个建造方法construct(),在该方法中调用了builder对象的构造部件的方法,最后返回一个产品对象
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder
}
public void setBuilder(Builder builder) {
this.builder = builder;
}
// 产品构建与组装方法
public Product construct() {
builder.builderPartA();
return builder.getResult();
}
}
客户端代码
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
建造者模式与抽象工厂模式的区别与共同点
建造者模式返回一个完成的复杂产品
抽象工厂模式返回一系列相关的产品
抽象模式中,客户端通过选择具体的工厂来生成所需对象
建造者模式中,客户端通过指定具体建造者类型来指导Director类如何去生成对象,侧重于一步步构造一个复杂对象
实例:游戏角色类
构造图
代码仓库
适用环境
- 需要生成的产品对象有复杂的内部结构
- 这些产品对象通常包含多个成员变量
- 需要生成的产品对象的属性相互依赖
- 需要指定其生成顺序
- 对象的创建过程独立于创建该对象的类
- 在建造者模式中通过引入指挥者类将创建过程封装在指挥者类中,而不是在建造者类和客户类中
- 隔离复杂对象的创建和使用
- 使得相同的创建过程可以创建不同的产品
原型模式
使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象
结构
结构图
- Prototype(抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类
- ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在方法中返回自己的一个克隆对象
- Client类
浅克隆
引用类型只复制地址
深克隆
全部复制一遍
实例
结构图
代码