设计模式二:工厂模式
作者:互联网
从简单工厂模式到工厂方法模式
从设计模式的类型上来说,简单工厂模式属于创建型模式,又叫作静态工厂模式,但不属于GoF的23种设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,被创建的实例通常都具有共同的父类。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是工厂方法模式和抽象工厂的基础和初步实现。其主要目的是:
- 不向客户透露对象实例化的细节
- 通过通用接口创建对象
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
简单工厂模式包括如下三种角色:
- 简单工厂:负责实现创建所有实例的内部逻辑,具体构造细节是在一个个
if/else
分支或者switch/case
分支里面 - 抽象产品:负责描述所有实例所共有的公共接口
- 具体产品:简单工厂模式的创建目标
简单工厂模式的UML类图如下:
下面给出一个例子说明简单工厂模式。
假设有一个蛋糕店,可以生产水果蛋糕、巧克力蛋糕、芝士蛋糕等,只要你提前预定蛋糕的类型,蛋糕店就可以给你生产出来。这里的蛋糕店就是一个简单工厂,水果蛋糕、巧克力蛋糕、芝士蛋糕就是具体产品。
程序代码如下:
/**
* 抽象产品
*/
public interface Cake {
void cooking();
void packing();
}
/**
* 具体产品
*/
public class FruitCake implements Cake {
@Override
public void cooking() {
System.out.println("水果蛋糕制作中...");
}
@Override
public void packing() {
System.out.println("水果蛋糕打包中...");
}
}
public class ChocolateCake implements Cake {
@Override
public void cooking() {
System.out.println("巧克力蛋糕制作中...");
}
@Override
public void packing() {
System.out.println("巧克力蛋糕打包中...");
}
}
public class CheeseCake implements Cake {
@Override
public void cooking() {
System.out.println("芝士蛋糕制作中...");
}
@Override
public void packing() {
System.out.println("芝士蛋糕打包中...");
}
}
/**
* 简单工厂
*/
public class Bakery {
public static Cake makeCake(String type) {
if ("水果".equals(type)) {
return new FruitCake();
} else if ("巧克力".equals(type)) {
return new ChocolateCake();
} else if ("芝士".equals(type)) {
return new CheeseCake();
} else {
System.out.println("抱歉!蛋糕房无法生产您所需的蛋糕");
return null;
}
}
}
/**
* 测试类
*/
public class FactoryTest {
public static void main(String[] args) {
Cake fruitCake = Bakery.makeCake("水果");
if (fruitCake != null) {
fruitCake.cooking();
fruitCake.packing();
}
Cake chocolateCake = Bakery.makeCake("巧克力");
if (chocolateCake != null) {
chocolateCake.cooking();
chocolateCake.packing();
}
Cake cheeseCake = Bakery.makeCake("芝士");
if (cheeseCake != null) {
cheeseCake.cooking();
cheeseCake.packing();
}
}
}
测试结果:
简单工厂模式具有如下优点:
- 简单工厂模式将对象的创建与对象的使用分离,有利于功能的复用和系统的维护
- 客户端无需知道所创建的具体产品的类名,只需知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量
- 可以通过引入配置文件,可以在不修改任何客户端代码的情况下跟换和增加新的具体产品类,在一定程度上提高了系统的灵活性
缺点:
- 工厂类集中了所有产品逻辑,一旦不能工作,整个系统都会收到影响
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,违背了“开闭原则”
工厂方法模式
工厂方法模式的定义:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中。
工厂方法模式又称为工厂模式,也叫虚拟构造器或者多态工厂模式,属于创建型模式。
工厂方法模式包含的角色如下:
- 抽象工厂:将具体工厂的实现隐藏起来,如果具体工厂实现类内部发生变化,对外部客户端的调用没有任何影响。抽象工厂类具有多态性,所以不能实例化,需要根据具体工厂类的不同实现来完成产品对象的创建。
- 具体工厂:具体工厂类时依赖于具体的产品的,如果具体产品增加或创建方式改变,只需对具体工厂类做修改,而抽象工厂不需修改。
- 抽象产品:抽象产品类向任何发出产品对象创建的客户端屏蔽了产品的细节,而这些细节有具体产品来实现。
- 具体产品:具体产品具有产品对象的数据和服务,客户端通过获取所需要的产品对象,来完成特定的业务流程。
工厂方法模式的UML类图如下:
下面通过一个例子来说明工厂方法模式
OEM制造商可以制造Dell、Sony、Acer和Lenovo等品牌笔记本,如果一次同时生产多个品牌的笔记本的话,有些不利于后期管理,比如加入了新的品牌后,就可能有许多设备上的改动。对此成立了一些子厂,每个子厂只做一种品牌的电脑,而OEM制造商作为核心总部。核心工厂不再负责创建等具体产品,把这些分派给自己的子厂,而核心工厂只需负责制定规范即可。
使用工厂模式模拟笔记本生产的UML类图如下:
示例代码如下:
1.抽象产品类——Laptop.java
public abstract class Laptop {
private String brand;
public Laptop() {
}
public Laptop(String brand) {
this.brand = brand;
}
public abstract void printId();
public void getDescription() {
System.out.println("电脑品牌:" + this.brand);
}
}
2.具体实现类——DellLaptop.java、AcerLaptop.java、LenovoLaptop.java
public class DellLaptop extends Laptop {
private static final String brand = "DELL";
private static int id;
public DellLaptop() {
super(brand);
id = 1000;
}
@Override
public void printId() {
System.out.println("序列号:" + id++);
}
}
public class AcerLaptop extends Laptop {
private static final String brand = "ACER";
private static int id;
public AcerLaptop() {
super(brand);
id = 2000;
}
@Override
public void printId() {
System.out.println("序列号:" + id++);
}
}
public class LenovoLaptop extends Laptop {
private static final String brand = "LENOVO";
private static int id;
public LenovoLaptop() {
super(brand);
id = 3000;
}
@Override
public void printId() {
System.out.println("序列号:" + id++);
}
}
3.抽象工厂类——LaptopFactory.java
public interface LaptopFactory {
Laptop produce();
void afterSaleService();
}
4.具体工厂类——DellFactory.java、AcerFactory.java、LenovoFactory.java
public class DellFactory implements LaptopFactory {
@Override
public Laptop produce() {
return new DellLaptop();
}
@Override
public void afterSaleService() {
System.out.println("戴尔售后为您服务!");
}
}
public class AcerFactory implements LaptopFactory {
@Override
public Laptop produce() {
return new AcerLaptop();
}
@Override
public void afterSaleService() {
System.out.println("宏基售后为您服务!");
}
}
ublic class LenovoFactory implements LaptopFactory {
@Override
public Laptop produce() {
return new LenovoLaptop();
}
@Override
public void afterSaleService() {
System.out.println("联想售后为您服务!");
}
}
5.测试类
public class FactoryTest {
public static void main(String[] args) {
LaptopFactory f1 = new DellFactory(); // 生产两台戴尔电脑
Laptop p1 = f1.produce();
Laptop p2 = f1.produce();
p1.getDescription();
p1.printId();
p2.getDescription();
p2.printId();
LaptopFactory f2 = new AcerFactory(); // 生产两台宏基电脑
Laptop p3 = f2.produce();
Laptop p4 = f2.produce();
p3.getDescription();
p3.printId();
p4.getDescription();
p4.printId();
LaptopFactory f3 = new LenovoFactory(); // 生产两台联想电脑
Laptop p5 = f3.produce();
Laptop p6 = f3.produce();
p5.getDescription();
p5.printId();
p6.getDescription();
p6.printId();
}
}
测试结果:
标签:void,模式,public,工厂,Override,设计模式,Laptop 来源: https://blog.csdn.net/sun_of_Dec/article/details/113616796