经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
工厂模式
来源:cnblogs  作者:TysonLee  时间:2019/6/28 8:50:05  对本文有异议

目录

  1. 简单工厂

  2. 工厂方法

  3. 抽象工厂

简单工厂

  定义:

  提供一个创建对象实例的功能,而无需关心具体的实现。被创建的实例对象可以是接口,抽象类,也可以是具体的类

  角色:

  工厂(creator)角色

    简单工厂的核心,负责具体类的创建,实现创建对象的内部逻辑,返回抽象产品角色。工厂类创建产品的方法可以被外界直接调用,创建所需要的对象。

  抽象(Product)产品角色

    简单工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。

  具体(ConcreteProduct)产品角色

    是简单工厂创建的目标,所创建的对象都是具体类的实例。

  实现:

  以person为例,具体产品为man,women,工厂角色为personFactory

  1. package com.lxlyq.factoryPattern.simpleFactory;
  2. /**
  3. * 抽象产品
  4. */
  5. public abstract class Person {
  6. private String name;
  7. private String age;
  8. public abstract void seeName();
  9.  
  10. public String getName() {
  11. return name;
  12. }
  13.  
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17.  
  18. public String getAge() {
  19. return age;
  20. }
  21.  
  22. public void setAge(String age) {
  23. this.age = age;
  24. }
  25. }

  

  1. package com.lxlyq.factoryPattern.simpleFactory;
  2.  
  3. public class Man extends Person {
  4. public Man() {}
  5. public Man(String name){
  6. this.setName(name);
  7. }
  8. @Override
  9. public void seeName() {
  10. System.out.println(this.getName());
  11. }
  12. }

  

  1. package com.lxlyq.factoryPattern.simpleFactory;
  2.  
  3. public class Women extends Person {
  4. public Women(){}
  5. public Women(String name) {
  6. this.setName(name);
  7. }
  8. @Override
  9. public void seeName() {
  10. System.out.println(this.getName());
  11. }
  12. }

  

  1. package com.lxlyq.factoryPattern.simpleFactory;
  2.  
  3. /**
  4. * 提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类
  5. */
  6. public class PersonFactory {
  7. public static final int MAN = 1;
  8. public static final int WOMEN = 2;
  9. public Person createMan(int type, String name) {
  10. switch (type) {
  11. case MAN:
  12. return new Man(name);
  13. case WOMEN:
  14. return new Women(name);
  15. default:
  16. throw new RuntimeException("don't has type");
  17. }
  18. }
  19. }

  客服端调用

  1. package com.lxlyq.factoryPattern.simpleFactory;
  2.  
  3. public class SimpleFactoryDemo {
  4. public static void main(String[] args) {
  5. Person man = new PersonFactory().createMan(PersonFactory.MAN, "women");
  6. man.seeName();
  7. }
  8. }

 优缺点

  优点:

    客户端只需创建一个工厂,而不用担心对象具体怎么实现。

  缺点:

    每次增加一个产品时,都需要更改工厂类,增加case或elseif判断创建新的产品对象,使得维护变得困难。

  使用场景

  • 工厂类负责创建的对象比较少;
  • 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
  • 由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
      注:工厂类应该只有一个,实际应用应该考虑成单例。

工厂方法

  定义:

       工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。

  角色:

  抽象工厂(creator)角色

    工厂方法的核心,与应用程序无关。提供一公共接口创建抽象产品方法,具体的实现由具体工厂实现。

  具体工厂(ConcreateCreator)角色

    对应简单工厂的工厂类,负责具体类的创建,实现创建对象的内部逻辑,返回抽象产品角色。工厂类创建产品的方法可以被外界直接调用,创建所需要的对象。但是不同的是,一个具体工厂只创建一个产品。所有的具体工厂都必须实现抽象工厂类。

  抽象产品(Product)角色

    具体工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。抽象工厂返回的类型。

  具体产品(ConcreteProduct)角色

    这个角色实现了抽象产品角色所定义的公共接口。具体工厂创建的目标,所创建的对象都是具体类的实例。

  实现:

  以汽车工厂为例,有宝马工厂,有奔驰工厂,汽车抽象类,奔驰,宝马,具体如下

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2. /**
  3. * 抽象产品
  4. */
  5. public abstract class Car {
  6. private String name;
  7. public abstract void driver();
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. }

  

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2.  
  3. /**
  4. * 宝马
  5. */
  6. public class BaoMaCar extends Car {
  7. {
  8. this.setName("baoMaCar");
  9. }
  10. @Override
  11. public void driver() {
  12. System.out.println(this.getName());
  13. }
  14. }

  

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2.  
  3. /**
  4. * 奔驰
  5. */
  6. public class BenCiCar extends Car {
  7. {
  8. this.setName("benCiCar");
  9. }
  10. @Override
  11. public void driver() {
  12. System.out.println(this.getName());
  13. }
  14. }

  

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2. /**
  3. * 工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
  4. */
  5.  
  6. public abstract class CarFactory {
  7. private String carName;
  8. public abstract Car createCar();
  9. public String getCarName() {
  10. return carName;
  11. }
  12. public void setCarName(String carName) {
  13. this.carName = carName;
  14. }
  15. }

  

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2.  
  3. /**
  4. * 奔驰工厂
  5. */
  6. public class BenCiFactory extends CarFactory {
  7. {
  8. this.setCarName("benCi");
  9. }
  10. @Override
  11. public Car createCar() {
  12. return new BenCiCar();
  13. }
  14. }

  

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2.  
  3. /**
  4. * 宝马工厂
  5. */
  6. public class BaoMaFactory extends CarFactory {
  7. {
  8. this.setCarName("baoMa");
  9. }
  10. @Override
  11. public Car createCar() {
  12. return new BaoMaCar();
  13. }
  14. }

  

  1. package com.lxlyq.factoryPattern.factoryMethod;
  2.  
  3. /**
  4. * 测试
  5. */
  6. public class FactoryMethodDemo {
  7. public static void main(String[] args) {
  8. Car baoMaCar = new BaoMaFactory().createCar();
  9. baoMaCar.driver();
  10. Car benCiCar = new BenCiFactory().createCar();
  11. benCiCar.driver();
  12. }
  13. }

  

 优缺点

  优点:

    客户端不需要知道具体的产品,只有知道产品对应的工厂类。

    增加一个产品只用增加一个具体工厂实现抽象工厂,增加一个具体产品实现抽象产品,而不用处理以前的代码,符合开闭原则。

  缺点:

    产品与工厂类都是成对出现,这使得系统中的类越来越多。

  使用场景

  • 对于某个产品,调用者清楚需要实例化那个具体工厂来生产需要使用的实例;
  • 调用方只是需要一种产品,而不想知道也不需要知道它由那个工厂生产。由生产者根据系统环境或其他条件创建一个工厂返回给调用方,调用方通过工厂创建对象,这个决策对于调用方是透明的;
      注:具体工厂类应该只有一个,实际应用应该考虑成单例。

抽象工厂

定义:

      抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。抽象工厂模式也称Kit模式,它属于类创建型模式。

  角色:

  抽象工厂(creator)角色

    抽象工厂的核心,它包含多个创建产品的方法 ,可以创建多个不同等级的产品。所有需要创建的不同等级的产品都需要在工厂中定义一个方法。

  具体工厂(ConcreateCreator)角色

    实现了抽象工厂的抽象方法,完成了具体产品的创建。具体工厂创建的产品应该至少2个。

  抽象产品(Product)角色

    具体工厂创建的所有对象的父类,它描述了所有实例所共有的公共接口。抽象工厂返回的类型。

  具体产品(ConcreteProduct)角色

    这个角色实现了抽象产品角色所定义的公共接口。具体工厂创建的目标,所创建的对象都是具体类的实例。

  实现:

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 抽象产品
  5. */
  6. public interface Shape {
  7. void draw();
  8. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 产品种类
  5. */
  6. public abstract class Circle implements Shape {
  7. @Override
  8. public abstract void draw();
  9. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 产品种类
  5. */
  6. public abstract class Rectangle implements Shape {
  7. @Override
  8. public abstract void draw();
  9. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 不同等级
  5. */
  6. public class BlueCircle extends Circle {
  7. @Override
  8. public void draw() {
  9. System.out.println("blueCircle");
  10. }
  11. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. public class BlueRectangle extends Rectangle {
  4. @Override
  5. public void draw() {
  6. System.out.println("blueRectangle");
  7. }
  8. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. public class RedCircle extends Circle {
  4. @Override
  5. public void draw() {
  6. System.out.println("draw redCircle");
  7. }
  8. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. public class RedRectangle extends Rectangle {
  4. @Override
  5. public void draw() {
  6. System.out.println("draw RedRectangle");
  7. }
  8. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
  5. * 抽象工厂模式也称Kit模式,它属于类创建型模式。
  6. */
  7. public interface ShapeFactory {
  8. Shape getCircle();
  9. Shape getRectangle();
  10. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 产品族1工厂
  5. */
  6. public class BlueShapeFactory implements ShapeFactory {
  7. @Override
  8. public Shape getCircle() {
  9. return new BlueCircle();
  10. }
  11.  
  12. @Override
  13. public Shape getRectangle() {
  14. return new BlueRectangle();
  15. }
  16. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. /**
  4. * 产品族2工厂
  5. */
  6. public class RedShapeFactory implements ShapeFactory{
  7.  
  8. @Override
  9. public Shape getCircle() {
  10. return new RedCircle();
  11. }
  12.  
  13. @Override
  14. public Shape getRectangle() {
  15. return new RedRectangle();
  16. }
  17. }

  

  1. package com.lxlyq.factoryPattern.abstractFactory;
  2.  
  3. public class AbstractFactoryDemo {
  4. public static void main(String[] args) {
  5. ShapeFactory blueShapeFactory = new BlueShapeFactory();
  6. Shape circle = blueShapeFactory.getCircle();
  7. Shape rectangle = blueShapeFactory.getRectangle();
  8. circle.draw();
  9. rectangle.draw();
  10. // 切换工厂
  11. ShapeFactory redShapeFactory = new RedShapeFactory();
  12. circle = redShapeFactory.getCircle();
  13. rectangle = redShapeFactory.getRectangle();
  14. circle.draw();
  15. rectangle.draw();
  16. }
  17. }

  从demo中知道,我们切管产品族只需要切换工厂即可。

 优缺点

  优点:

    它分离了具体的类;

    它使得易于交换产品系列;

    它有利于产品的一致性;

    增加一个产品产品族只用增加一个具体工厂实现抽象工厂,增加具体产品实现抽象产品,而不用处理以前的代码,符合开闭原则。

  缺点:

    当新增一个产品种类时,(新增一个多边形),那么需要在抽象工厂中增加一个创建多边形的方法,从而之前写的所有具体工厂都需要变动,不符合开闭原则(难以支持新种类的产品)。

  使用场景

  • 抽象工厂模式最早的应用是用于创建属于不同操作系统的视窗构件。
  • 当我们需要多个产品族,而每次只单独使用其中一个产品族时(如操作系统中的控件,产品族分为Linux,windows,有linux按钮,windows按钮,linux文本,windows文本等。我们需要根据系统来切换不同的产品族,达到使用不同系统的控件)。
      注:具体工厂类应该只有一个,实际应用应该考虑成单例。

总结:

  工厂模式帮我们统一生产对象,我们不需要知道对象具体生成逻辑。使得对象的创建与使用解耦。

 

原文链接:http://www.cnblogs.com/tysonlee/p/11080624.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号