简介
工厂模式是一种创建模式,因为此模式提供了更好的方法来创建对象。在工厂模式中,我们创建对象而不将创建逻辑暴露给客户
简单来说就是工厂模式就是用来封装创建对象的工具类的。
工厂模式一共分为三种,简单工厂(静态工厂) ,工厂方法 ,抽象工厂
简单工厂(静态工厂)
有一个工厂类拥有一个静态的方法, 用来产生产品实例, 通过传递参数的不同来区分生成哪个产品实例.
先来看看它的组成:
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
//描述产品
abstract class Drinks {
String name = null;
}
//具体产品
class Coke extends Drinks {
public Coke() {
name = "可乐";
}
}
//具体产品
class Coffee extends Drinks {
public Coffee() {
name = "咖啡";
}
}
//具体产品
class Tea extends Drinks {
public Tea() {
name = "茶";
}
}
//生产产品的工厂
class Factory{
public static Drinks cerateDuicks(String drinks){
switch (drinks){
case "A": return new Coke();
case "B": return new Coffee();
case "C": return new Tea();
}
return null;
}
}
//测试
class Test{
public static void main(String[] args) {
Drinks drinks = Factory.cerateDuicks("A");
System.out.println(drinks.name);
Drinks drinks1 = Factory.cerateDuicks("C");
System.out.println(drinks1.name);
}
}
使用这中简单的工厂设计模式有一个弊端,那就是只有一个工厂来产品,如果我们需要新增一种新型产品饮料,就需要去对这个
工厂进行改造。增加了代码的复杂度,代码的耦合度不够低。这个时候工厂方法就出来了,完美的解决了我们的问题。
工厂方法模式
又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。一种常用的对象创建型设计模式,此模式的核心精神是封装 类中不变的部分。
作用:将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
产品类:
//描述产品
abstract class Drinks {
String name = null;
}
//具体产品
class Coke extends Drinks {
public Coke() {
name = "可乐";
}
}
//具体产品
class Coffee extends Drinks {
public Coffee() {
name = "咖啡";
}
}
//具体产品
class Tea extends Drinks {
public Tea() {
name = "茶";
}
}
工厂类:
//工厂描述
abstract class Factory{
abstract Drinks cerateDrinks();
}
//生产可乐的具体工厂
class CokeFactory extends Factory{
@Override
public Drinks cerateDrinks() {
return new Coke();
}
}
//生产咖啡的具体工厂
class CoffeeFactory extends Factory{
@Override
public Drinks cerateDrinks() {
return new Coffee();
}
}
//生产茶的具体工厂
class TeaFactory extends Factory{
@Override
public Drinks cerateDrinks() {
return new Tea();
}
}
测试类:
class Test{
public static void main(String[] args) {
//创建制造可乐的工厂来生产可乐
Factory factory = new CokeFactory();
factory.cerateDrinks();
//创建制造咖啡的工厂来生产咖啡
Factory factory1 = new CoffeeFactory();
factory1.cerateDrinks();
}
}
当我们利用工厂方法模式去生产产品时会非常方便即需要什么产品建立什么产品的工厂就可以了,当我们需要新增一种新型饮料的时候,我们也只需要创建一个新的具体工厂类和具体产品类就可以了。
工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口,但使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。另外工厂方法模式的工厂会出现一个工厂只能生产一种产品,这也不是我们想看到的。
抽象工厂模式
定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。
解决的问题:每个工厂只能创建一类产品(工厂方法模式)
抽象产品类:
//抽象食物类
abstract class Food{
String type;
}
//抽象面包类
abstract class Bread extends Food{
String name;
public Bread() {
this.type = "面包";
}
}
//抽象饮料类
abstract class Drinks extends Food{
String name;
public Drinks() {
this.type = "饮料";
}
}
具体产品类:
//具体饮料咖啡
class Coffee extends Drinks {
public Coffee() {
name = "咖啡";
}
}
//具体面包加糖面包
class SugarBread extends Bread {
public SugarBread() {
this.name = "加糖面包";
}
}
//具体面包全麦面包
class GrahamBread extends Drinks {
public GrahamBread() {
this.name = "全麦面包";
}
}
抽象工厂接口:
//抽象工厂类接口
interface Fatory{
public Food createDrinks();
public Food createBread();
}
具体工厂类:
//具体工厂A
class FactoryA implements Fatory{
@Override
public Drinks createDrinks() {
return new Coke();
}
@Override
public Bread createBread() {
return new SugarBread();
}
}
测试类:
public class Test{
public static void main(String[] args) {
FactoryA fatoryA = new FactoryA();
Bread bread = (Bread) fatoryA.createBread();
System.out.println(bread.type + " " + bread.name);
Drinks drinks = (Drinks) fatoryA.createDrinks();
System.out.println(drinks.type + " " + drinks.name);
}
}
总结
工厂方法模式解决了简单工厂模式的“开放 - 关闭原则(添加产品过程太复杂);
抽象工厂模式解决了工厂方法模式一个具体工厂只能创建一类产品;