设计模式:简单工厂模式


设计模式:简单工厂模式

1. 基本概念

1.1 原理

简单工厂模式是一种创建型模式,即它主要的作用是用于创建某些类的实例。简单工厂模式的主要内容是定义一个工厂类和多个产品类,工厂类包含一个用户可以调用的工厂方法。该工厂方法根据用户传递给它的不同参数而创建不同产品类的实例并返回给用户。

通过引入简单工厂模式,用户将不再关心它所需要的产品类实例是如何被创建的,因为这一部分职责已经被委托给了工厂类的工厂方法;用户现在要做的只是按照它的业务逻辑使用该产品类实例。

因为工厂方法可以返回多种产品类的实例,而用户要能够按照统一的方式使用它们,那么这些产品类应该具有一个共同的父类。该父类定义了这些产品类共同的接口,而具体的产品类对这些接口进行不同的实现。

此外,在一些严格类型的编程语言(比如C++、Java)中,一个函数或者一个方法只能返回一种类型;这也决定了所有的产品类应该具有一个公共的父类。

为了方便,我们通常将工厂方法定义为工厂类的静态方法,这样我们无需实例化该工厂类就可以直接在它之上调用它的工厂方法。因此,简单工厂模式也被称为静态工厂方法(Static Factory Method)模式。

在设计模式领域最著名的著作《设计模式:可复用面向对象软件的基础》中,并没有收录简单工厂模式,而且有些人认为严格来说简单工厂甚至不能算是一种设计模式。但是理解简单工厂对于理解工厂方法模式和抽象工厂模式有很大的帮助,所以这里我们依旧将它当作一种设计模式来进行讲解。

1.2 结构


设计模式:简单工厂模式

图1 简单工厂模式的类图结构

简单工厂模式的类图如图1所示,这些类在简单工厂模式中扮演下面这些角色:

Client:用户代码,它调用工厂类的工厂方法并使用返回的具体产品类的实例。

Factory:工厂类,它有一个工厂方法;它根据用户传递的不同参数而创建并返回某一具体产品类的实例。

Product:所有产品类的公共父类,它定义所有产品类的接口以供用户调用。

ConcreteProduct:具体的产品类,继承自Product,实现Product定义的接口;它的实例由工厂方法创建。

2. 示例

笔记本电脑、智能手机和平板电脑都属于计算机设备,用户可以用任意一种计算机设备来工作、聊天和观看电影。我们使用简单工厂模式以及Java编程语言来实现这一示例,为此我们还要定义一个工厂类,由它根据用户的要求来生产实际的计算机产品。

2.1 定义产品类

2.1.1 所有产品类的公共父类

<code>/*
* 所有产品类的公共父类,它定义3个接口:work()、chat()和watchMovie()
*/
public abstract class Computer {
public abstract void work();
public abstract void chat();
public abstract void watchMovie();
};/<code>

2.1.2 笔记本电脑类Laptop

<code>/*
* 具体的产品类Laptop,它继承自Computer
*/
public class Laptop extends Computer {
@Override
public void work() {
System.out.println("Work by Laptop.");
}

@Override
public void chat() {
System.out.println("Chat by Laptop.");
}

@Override
public void watchMovie() {
System.out.println("Watch movie by Laptop.");
}
}/<code>

2.1.3 智能手机类SmartPhone

<code>/*
* 具体的产品类SmartPhone,它继承自Computer
*/
public class SmartPhone extends Computer {
@Override
public void work() {
System.out.println("Work by SmartPhone.");
}

@Override
public void chat() {

System.out.println("Chat by SmartPhone.");
}

@Override
public void watchMovie() {
System.out.println("Watch movie by SmartPhone.");
}
}/<code>

2.1.4 平板电脑类Tablet

<code>/*
* 具体的产品类Tablet,它继承自Computer
*/
public class Tablet extends Computer {
@Override
public void work() {
System.out.println("Work by Tablet.");
}

@Override
public void chat() {
System.out.println("Chat by Tablet.");
}

@Override
public void watchMovie() {
System.out.println("Watch movie by Tablet.");
}
}/<code>

2.2 定义工厂类

<code>/*
* 简单工厂类,提供工厂方法createComputer
*/
public class SimpleFactory {
/*
* 工厂方法,根据参数的不同而创建不同的计算机产品;
* 如果参数错误则抛出异常。
*/
public static Computer createComputer(String type) {
Computer computer = null;
switch(type) {

case "laptop":
computer = new Laptop();
break;

case "smartPhone":
computer = new SmartPhone();
break;

case "tablet":
computer = new Tablet();
break;

default:
throw new IllegalArgumentException("type参数错误。");
}

return computer;
}
}/<code>

2.3 定义用户代码

<code>/*
* 用户代码,它用不同的参数调用工厂方法;
* 并使用返回的具体产品类的实例。
*/
public class Client {
public static void main(String[] args) {
/*
* 请求工厂类生产一个笔记本电脑(laptop)
*/
Computer computer = SimpleFactory.createComputer("laptop");
computer.work();
computer.chat();
computer.watchMovie();

/*
* 请求工厂类生产一个平板电脑(tablet)
*/
computer = SimpleFactory.createComputer("tablet");
computer.work();
computer.chat();
computer.watchMovie();

}
}/<code>

3. 优缺点和使用场景

简单工厂的优点就是它分离了产品类实例的创建和使用,在一定程度上实现了代码的解耦。用户代码只关心如何使用产品而不关心产品是如何被创建的,当需要修改产品的创建逻辑的时候可以只修改工厂类而不需要修改用户代码。

简单工厂模式的缺点就是产品类的创建逻辑全都集中在工厂类中,每当增加产品类时都要修改工厂类,即要修改已存在的代码,这违背了开闭原则。而且当产品类很多的时候,工厂类中的创建逻辑将变得非常复杂,当逻辑变得越来越复杂的时候就越容易出错。

综上所述,简单工厂模式适用于用户不关心产品类如何被创建而只关心使用产品类,产品类数量较小且稳定的情况下。

(完)


分享到:


相關文章: