概述
这是设计模式中最简单的模式,虽然他不是23中GOF中的一种,但是应用也是很频繁的;这也是学习其他设计模式的基础,在简单工厂模式中,只需要记住一个参数就可以获取所需对象实例,他提供专门的核心工厂类来负责对象的创建,实现对象创建和使用的分离。
通过一个例子来理解简单工厂模式:有一个农场,当用户需要一中水果时该农场能够根据用户所描述的水果名称返回水果。这里面,水果农场被称为工厂,而生成的水果被称为产品,水果的名称就是参数,工厂可以根据参数返回相应的产品,这就是简单工厂模式。
首先需要创建各种不同产品对象的相关代码封装到不同的类中,这些类具体的产品类,然后将他们公共的代码进行抽取和提取后封装在一个抽象产品中,每一个具体产品类都是抽象产品的子类,再提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数不同创建不同的具体产品对象;客户端只需要调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。
由于在简单工厂模式中用于创建实例的方法为静态方法,因此又称为静态工厂方法模式,简单工厂模式的要点在于当用户需要什么时,只需要传入一个正确参数就可以获取所需要的对象,而无需知道其创建细节。
简单工厂模式结构
(1)Factory(工厂角色):即工厂类,负责创建所有产品实例的内部逻辑,可以被外部直接调用,创建所需要创建的对象,提供了静态的工厂方法,返回类型为抽象产品类型(Product)。
(2)Product(抽象产品角色):它是工厂类创建的所有对象的父类,封装了各种产品对象的公有方法。
(3)ConcreteProduct(具体产品角色):它是简单工厂模式创建的目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。
简单工厂模式的实现
抽象产品角色类:包含了共有方法,和一些抽象方法,可以供不同的产品类来实现。
public abstract class Product{
//所有产品类的公共业务方法
public void methodSame(){
//共有方法的实现
}
//声明抽象业务方法
public abstract void methodDiff();
}
具体产品类实现了抽象产品类生命的抽象业务方法,不同的具体产品类可以提供不同的实现。
public class ConcreteProduct extends Product{
//实现业务具体方法
public void methodDiff(){
//业务方法的实现
}
}
工厂类,根据提供的参数返回所需要的实例,不再像以前new关键字来直接创建产品对象。
public class Factory{
//静态工厂方法
public static Product getProduct(String arg){
Product product = null;
if(arg.equailsIgnoreCase("A")){
product = new ConcreteProductA();
//初始化设置product
}else if(arg.equailsIgnoreCase("A")){
product = new ConcreteProductB();
//初始化设置product
}
return product;
}
}
客户端测试代码:
public class Client{
public static void main(String args[]){
Product product;
product = Factory.getProduct("A"); //通过工厂类创建产品对象
product.methodSame();
product.methodDiff();
}
}
实例
public interface Chart {
public void display();
}
public class HistogramChart implements Chart {
public HistogramChart() {
System.out.println("创建柱状图。");
}
@Override
public void display() {
System.out.println("展示柱状图。");
}
}
public class PieChart implements Chart {
public PieChart() {
System.out.println("创建饼状图。");
}
@Override
public void display() {
System.out.println("展示饼状图。");
}
}
public class LineChart implements Chart {
public LineChart() {
System.out.println("创建折线图。");
}
@Override
public void display() {
System.out.println("展示折线图。");
}
}
public class ChartFactory {
public static Chart getChart(String arg){
Chart chart = null;
if (arg.equalsIgnoreCase("Histogram")){
chart = new HistogramChart();
System.out.println("初始化设置柱状图。");
}
if (arg.equalsIgnoreCase("Pie")){
chart = new PieChart();
System.out.println("初始化设置饼状图。");
}
if (arg.equalsIgnoreCase("Line")){
chart = new LineChart();
System.out.println("初始化设置折线图。");
}
return chart;
}
}
public class ChartFactory {
public static Chart getChart(String arg){
Chart chart = null;
if (arg.equalsIgnoreCase("Histogram")){
chart = new HistogramChart();
System.out.println("初始化设置柱状图。");
}
if (arg.equalsIgnoreCase("Pie")){
chart = new PieChart();
System.out.println("初始化设置饼状图。");
}
if (arg.equalsIgnoreCase("Line")){
chart = new LineChart();
System.out.println("初始化设置折线图。");
}
return chart;
}
}
分析实例
每次创建实例时,必须修改客户端代码,客户端代码需要重新编译,这违反了开闭原则。
可以将参数存储在XML文件中,客户端通过读取文件获取参数,怎样修改XML文件也不需要客户端重新编译。
XML文件读取方式不再细说。