一篇带你读懂工厂模式

工厂模式

简单工厂模式

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

实现

步骤 1

创建一个接口:

Shape.java

public interface Shape {    void draw();}

步骤 2

创建实现接口的实体类。

Rectangle.java

public class Rectangle implements Shape {    @Override    public void draw() {        System.out.println("Rectangle");    }}

Circle.java

public class Circle implements Shape {    @Override    public void draw() {        System.out.println("Circle");    }}

步骤 3

创建一个工厂,生成基于给定信息的实体类的对象。

ShapeFactory.java

public class ShapeFactory {

   //使用 getShape 方法获取形状类型的对象   public Shape getShape(String shapeType){      if(shapeType == null){         return null;      }              if(shapeType.equalsIgnoreCase("CIRCLE")){         return new Circle();      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){         return new Rectangle();      } else if(shapeType.equalsIgnoreCase("SQUARE")){         return new Square();      }      return null;   }}

步骤 4

使用该工厂,通过传递类型信息来获取实体类的对象。

FactoryPattern.java

public class FactoryPattern {    public static void main(String[] args) {        ShapeFactory shapeFactory=new ShapeFactory();

        //获取 Circle 的对象,并调用它的 draw 方法        Shape shape= shapeFactory.getShape("Circle");        //获取 Circle 的对象,并调用它的 draw 方法        shape.draw();

        Shape shape1= shapeFactory.getShape("RentAngle");        shape1.draw();    }

}

步骤 5

执行程序,输出结果:

Inside Circle::draw() method.Inside Rectangle::draw() method.

ps: 1.接口做为参数传递,传递的是实现了接口的对象; 2.接口作为类型返回,返回的是实现了接口的对象。

2. 工厂方法模式(Factory Method)

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,其UML类图如下:

也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。

接下来继续使用生产手机的例子来讲解该模式。

其中和产品相关的Phone类、MiPhone类和IPhone类的定义不变。

AbstractFactory类:生产不同产品的工厂的抽象类

public interface AbstractFactory {    Phone makePhone();}

XiaoMiFactory类:生产小米手机的工厂(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{    @Override    public Phone makePhone() {        return new MiPhone();    }}

AppleFactory类:生产苹果手机的工厂(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {    @Override    public Phone makePhone() {        return new IPhone();    }}

演示:

public class Demo {    public static void main(String[] arg) {        AbstractFactory miFactory = new XiaoMiFactory();        AbstractFactory appleFactory = new AppleFactory();        miFactory.makePhone();            // make xiaomi phone!        appleFactory.makePhone();        // make iphone!    }}

3. 抽象工厂模式(Abstract Factory)

上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生成另一种产品PC,应该怎么表示呢?

最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。

抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干。

其UML类图如下:

从上面类图结构中可以清楚的看到如何在工厂方法模式中通过增加新产品接口来实现产品的增加的。

接下来我们继续通过小米和苹果产品生产的例子来解释该模式。

为了弄清楚上面的结构,我们使用具体的产品和工厂来表示上面的UML类图,能更加清晰的看出模式是如何演变的:

PC类:定义PC产品的接口(AbstractPC)

public interface PC {    void make();}

MiPC类:定义小米电脑产品(MIPC)

public class MiPC implements PC {    public MiPC() {        this.make();    }    @Override    public void make() {        // TODO Auto-generated method stub        System.out.println("make xiaomi PC!");    }}

MAC类:定义苹果电脑产品(MAC)

public class MAC implements PC {    public MAC() {        this.make();    }    @Override    public void make() {        // TODO Auto-generated method stub        System.out.println("make MAC!");    }}

下面需要修改工厂相关的类的定义:

AbstractFactory类:增加PC产品制造接口

public interface AbstractFactory {    Phone makePhone();    PC makePC();}

XiaoMiFactory类:增加小米PC的制造(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{    @Override    public Phone makePhone() {        return new MiPhone();    }    @Override    public PC makePC() {        return new MiPC();    }}

AppleFactory类:增加苹果PC的制造(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {    @Override    public Phone makePhone() {        return new IPhone();    }    @Override    public PC makePC() {        return new MAC();    }}

演示:

public class Demo {    public static void main(String[] arg) {        AbstractFactory miFactory = new XiaoMiFactory();        AbstractFactory appleFactory = new AppleFactory();        miFactory.makePhone();            // make xiaomi phone!        miFactory.makePC();                // make xiaomi PC!        appleFactory.makePhone();        // make iphone!        appleFactory.makePC();            // make MAC!    }}

总结:

上面介绍的三种工厂模式有各自的应用场景,实际应用时能解决问题满足需求即可,可灵活变通,无所谓高级与低级。

此外无论哪种模式,由于可能封装了大量对象和工厂创建,新加产品需要修改已定义好的工厂相关的类,因此对于产品和工厂的扩展不太友好,利弊需要权衡一下。

(0)

相关推荐

  • 【设计模式】(四)抽象工厂模式(Abstract Factory Pattern)

    【设计模式】(四)抽象工厂模式(Abstract Factory Pattern)

  • 设计模式之工厂模式(factory pattern)

    工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式.该模式用于封装和管理对象的创建,是一种创建型模式.本文从一 ...

  • 【C++设计模式二】C++工厂模式

    (1)定义 简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑.为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂, ...

  • 一篇轻松带你读懂“青绿山水”的文章

    青绿山水,是山水画的一种, 用矿物质石青.石绿作为主色的山水画. 下面这幅是著名的青绿山水作品--明代绘画大师·张宏,所绘的一幅山水佳作<青绿山水图>! 明 | 张宏 这幅作品,是古代青绿 ...

  • 一篇文章,带你读懂如何训练孩子画画时的观察力?

    我们的绘画都是通过对事物的观察而表达出来的,只有通过观察才会分析比较出物体的区别和差异.通过观察,才会大量的搜集素材,扩大视野,丰富想像力.培养他们眼.脑.手综合适用的能力. 观察力是指一个人从周围世 ...

  • 这篇回答带你读懂这个“超级个体崛起”的时代

    一个人就是一家公司,普通人遵循什么样的生存法则才能在这一波个体崛起的红利中分上一杯羹,占据一席之地. 李佳琦和李子柒个人的年收入超过几家上市公司的营收,罗永浩用一年的时间偿还了4亿的欠款,辛巴一场直播 ...

  • 骨科精读 | 害怕遇到骨筋膜室综合征?带你读懂边界与解剖!

    小腿为骨筋膜室最常发生部位之一,掌握小腿四大骨筋膜室的边界及内容物,对理解小腿骨筋膜室的发病机制.临床表现及减压方法具有指导意义,汇总如下: 骨筋膜室由骨间膜.骨.肌间隔和深筋膜组成.小腿深筋膜在前面 ...

  • 一目了然,带你读懂17大名酒商标谱系

    大家都在看 河南省副食品有限公司党委圆满完成换届选举工作 人生就像一杯酒,喝了才会懂 会喝酒的人,是怎样的不一般?

  • 三分钟带你读懂股市杀猪盘

    一.什么是股市杀猪盘 股市杀猪盘又叫散户收割机,杀猪盘是网络流行词,是一种网络诱导股票投资.赌博等类型的诈骗方式.股市庄家高度控盘之后会把股票推到高位,但由于筹码大部分都在自己手中,无法变现.这时他们 ...

  • 三星堆“虞舜”的青铜器,带您读懂《尚书,舜典》

    #三星堆青铜器##虞舜##<尚书,舜典># 原创不易,支持请按"关注",和我一起发掘古文字的秘密吧! {上图为三星堆牛首青铜器,截图于三星堆博物馆官网} 一:三星堆的& ...

  • 一篇文章带你读懂湖田窑!资深藏家必看!

    湖田窑水晶莹玉润,白中泛青,色如湖蓝,极富情趣,刀法简捷明快,娴熟自然,结合造型.底足工艺特征判断,是开门的宋代湖田窑精品特征.湖田窑是汉族传统制瓷工艺中的珍品,位于今景德镇市东南湖田村,是中国宋.元 ...

  • “红杏枝头春意闹”| 带你读懂古诗词里的“通感”

    在王国维的<人间词话>中,有这么一句:红杏枝头春意闹,著一"闹"字,而境界全出.这首词出自宋祁之手,宋祁系宋代史学家.文学家,与欧阳修同编修<新唐书>,足见 ...