不积跬步,无以至千里;不积小流,无以成江海。
Java语言基础
Java的工厂设计模式
工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类。
工厂模式的形态
1:简单工厂(Simple Factory)
2:工厂方法(Factory Method)
3:抽象工厂(Abstract Factory)
简单工厂(Simple Factory)
又叫静态工厂,是工厂模式三中状态中结构最为简单的。主要有一个静态方法,用来接受参数,并根据参数来决定返回实现同一接口的不同类的实例。
具体的例子:假设一家工厂,几生产洗衣机,有生产冰箱,还有空调等等.
先为所有产品定义一个共同的产品接口:
interface Product{ }
接着我们让这个工厂的所有产品都必须实现此接口:
class Washer implements Product{ public Washer(){ System.out.println("洗衣机被制造了"); } } class Icebox implements Product{ public Icebox(){ System.out.println("冰箱被制造了"); } } class AirCondition implements Product{ public AirCondition(){ System.out.println("空调被制造了"); } }
一个工厂类,有它来负责生产以上的产品:
public class SimpleFactory { public static Product factory(String productName) throws Exception{ if (productName.equals("Washer")) { return new Washer(); }else if (productName.equals("Icebox")) { return new Icebox(); }else if (productName.equals("AirCondition")) { return new AirCondition(); }else { throw new Exception("没有该产品"); } } }
开始下定单:
public static void main(String[] args) { // TODO Auto-generated method stub try { SimpleFactory.factory("Washer"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
程序输出:
洗衣机被制造了
简单工厂的核心就是一个SimpleFactory类,他拥有必要的逻辑判断能力和所有产品的创建权利,我们只需要向把定单给他,就能得到我们想要的产品。
缺陷:
每次想要增加一种新产品的时候,都必须修改SimpleFactory的原代码。其次,当拥有很多很多产品的时候,而且产品之间又存在复杂的层次关系的时候,这个类必须拥有复杂的逻辑判断能力,其代码量也将不断地激增;且只要SimpleFactory类一出问题,系统就进入不能工作的状态。
工厂方法(Factory Method)
工厂方法为工厂类定义了接口,用多态来削弱了工厂类的职能,以下是工厂接口的定义:
interface Factory{ Product creat(); }
再来定义一个产品接口:
interface Product{ }
实现了产品接口的产品类:
class Washer implements Product{ public Washer() { System.out.println("洗衣机被制造了"); } } class Icebox implements Product{ public Icebox(){ System.out.println("冰箱被制造了"); } } class AirCondition implements Product{ public AirCondition(){ System.out.println("空调被制造了"); } }
工厂方法的核心部分,具体创建产品对象的具体工厂类:
class CreateWasher implements Factory{ @Override public Product creat() { // TODO Auto-generated method stub return new Washer(); } } class CreateIcebox implements Factory{ @Override public Product creat() { // TODO Auto-generated method stub return new Icebox(); } } class CreateAirCondition implements Factory{ @Override public Product creat() { // TODO Auto-generated method stub return new AirCondition(); } }
工厂方法和简单工厂的主要区别:简单工厂是把创建产品的职能都放在一个类里面,而工厂方法则把不同的产品放在实现了工厂接口的不同工厂类里面,这样就算其中一个工厂类出了问题,其他工厂类也能正常工作,互相不受影响,以后增加新产品,也只需要新增一个实现工厂接口工厂类,就能达到,不用修改已有的代码。
缺陷:
但工厂方法也有他局限的地方,那就是当面对的产品有复杂的等级结构的时候,例如,工厂除了生产家电外产品,还生产手机产品,这样一来家电是手机就是两大产品家族了,这两大家族下面包含了数量众多的产品,每个产品又有多个型号,这样就形成了一个复杂的产品树了。如果用工厂方法来设计这个产品家族系统,就必须为每个型号的产品创建一个对应的工厂类,当有数百种甚至上千种产品的时候,也必须要有对应的上百成千个工厂类,这就出现了传说的类爆炸,对于以后的维护来说,简直就是一场灾难。
抽象工厂(Factory Method)
在工厂方法的基础上引进了分类管理的概念;
工厂方法用来创建一个产品,它没有分类的概念,而抽象工厂则用于创建一系列产品,所以产品分类成了抽象工厂的重点,
我们继续用上面的例子来说明:
工厂生产的所有产品都用都用大写字母来标明它们的型号,比如冰箱,就有“冰箱-A",“冰箱-B",同样,其他的产品也都是遵守这个编号规则,于是就有了一下产品家族树:
冰箱:
冰箱-A
冰箱-B
洗衣机:
洗衣机-A
洗衣机-B
为冰箱和洗衣机分别定义两个产品接口,以对他们进行分类:
// 洗衣机接口 interface Washer{ } // 冰箱接口 interface Icebox{ }
创建这两个接口的具体产品:
class WasherA implements Washer{ public WasherA() { System.out.println("洗衣机-A被制造了"); } } class WasherB implements Washer{ public WasherB() { System.out.println("洗衣机-B被制造了"); } } class IceboxA implements Icebox{ public IceboxA(){ System.out.println("冰箱-A被制造了"); } } class IceboxB implements Icebox{ public IceboxB(){ System.out.println("冰箱-B被制造了"); } }
产品部分我们准备好了,接下来我们来处理工厂部分,我们先来定义工厂行为接口:
interface Factory{ Washer creatWasher(); Icebox creatIceboxx(); }
创造具体的工厂类,我们根据上面产品的接口,把型号A的产品分为一类,由一个工厂来管理,把型号为B的产品有另一个工厂管理,根据这个分类,我们可以实现如下的两个具体工厂类:
// 创建型号为A的产品工厂 class FactoryA implements Factory{ @Override // 创建洗衣机-A public Washer creatWasher() { // TODO Auto-generated method stub return new WasherA() { }; } @Override // 创建冰箱-A public Icebox creatIceboxx() { // TODO Auto-generated method stub return new IceboxA() { }; } } // 创建型号为B的产品工厂 class FactoryB implements Factory{ @Override // 创建洗衣机-B public Washer creatWasher() { // TODO Auto-generated method stub return new WasherB() { }; } @Override // 创建冰箱-B public Icebox creatIceboxx() { // TODO Auto-generated method stub return new IceboxB() { }; } }
在应用抽象工厂之前,要先对创建的对象进行系统的分类,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路。
博客借鉴:https://www.jb51.net/article/127702.htm