工厂模式(简单工厂,工厂方法,抽象工厂)

举报
ShaderJoy 发表于 2021/12/30 00:20:09 2021/12/30
【摘要】 1.简单工厂模式:      简单工厂模式又称静态工厂方法模式。从命名上就可以看出这个模式一定很简单。它存 在的目的很简单:定义一个用于创建对象的接口。 先来看看它的组成: 1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由 一个具体类实现...

1.简单工厂模式:

     简单工厂模式又称静态工厂方法模式。从命名上就可以看出这个模式一定很简单。它存
在的目的很简单:定义一个用于创建对象的接口
先来看看它的组成:

1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由

一个具体类实现。

2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽

象类来实现。

3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。


  
  1. //抽象产品角色
  2. public interface Fruit
  3. {
  4. public void get();
  5. }
  6. //具体产品角色
  7. public class Apple implements Fruit
  8. {
  9. public void get()
  10. {
  11. System.out.println("采摘苹果");
  12. }
  13. }
  14. public class Banana implements Fruit
  15. {
  16. public void get()
  17. {
  18. System.out.println("采摘香蕉");
  19. }
  20. }

  
  1. //工厂类角色
  2. public class FruitFactory
  3. {
  4. public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException
  5. {//工厂方法.注意返回类型为抽象产品角色
  6. // if(type.equalsIgnoreCase("apple"))
  7. // {
  8. // return Apple.class.newInstance();
  9. // }
  10. // else if(type.equalsIgnoreCase("banana"))
  11. // {
  12. // return Banana.class.newInstance();
  13. // }
  14. try
  15. {
  16. Class fruit=Class.forName(type);//type需要类名的全路径
  17. return (Fruit) fruit.newInstance();
  18. } catch (ClassNotFoundException e)
  19. {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. System.out.println("找不到相应的实例化类");
  24. return null;
  25. }
  26. }

  
  1. public class MainClass
  2. {
  3. /**
  4. * @param args
  5. * @throws IllegalAccessException
  6. * @throws InstantiationException
  7. */
  8. public static void main(String[] args) throws InstantiationException, IllegalAccessException
  9. {
  10. // TODO Auto-generated method stub
  11. //简单工厂模式
  12. // Fruit apple=FruitFactory.getFruit("apple");
  13. // apple.get();
  14. // Fruit banana=FruitFactory.getFruit("banana");
  15. // banana.get();
  16. Fruit apple=FruitFactory.getFruit("design.pattern.simplefactory.Apple");//注意是全路径
  17. apple.get();
  18. Fruit banana=FruitFactory.getFruit("design.pattern.simplefactory.Banana");
  19. banana.get();
  20. }
  21. }

2.工厂方法模式:

 工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这
样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分
担。

1) 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须

实现的接口或者必须继承的父类。在java 中它由抽象类或者接口来实现。

2) 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体

产品的对象。

3) 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在 java 中一般有抽象类

或者接口来实现。

4) 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在 java 中由具体的类

来实现。


  
  1. //抽象产品角色,具体产品角色与简单工厂模式类似,只是变得复杂了些,这里略。
  2. //抽象工厂角色
  3. public interface FruitFactoryInterface
  4. {
  5. public Fruit getFruit();
  6. }
  7. public class OrangeFactory implements FruitFactoryInterface
  8. {
  9. @Override
  10. public Fruit getFruit()
  11. {
  12. // TODO Auto-generated method stub
  13. return new Orange();
  14. }
  15. }
  16. public class PearFactory implements FruitFactoryInterface
  17. {
  18. @Override
  19. public Fruit getFruit()
  20. {
  21. // TODO Auto-generated method stub
  22. return new Pear();
  23. }
  24. }
  25. //应该和具体产品形成对应关系...
  26. public class MainClass
  27. {
  28. /**
  29. * @param args
  30. * @throws IllegalAccessException
  31. * @throws InstantiationException
  32. */
  33. public static void main(String[] args) throws InstantiationException, IllegalAccessException
  34. {
  35. // TODO Auto-generated method stub
  36. FruitFactoryInterface ffi_0=new PearFactory();//工厂方法模式
  37. Fruit pear=ffi_0.getFruit();
  38. pear.get();
  39. FruitFactoryInterface ffi_1=new OrangeFactory();
  40. Fruit orange=ffi_1.getFruit();
  41. orange.get();
  42. }
  43. }

缺点

可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。

解决办法

为了避免这种情况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。

简单工厂模式与工厂方法模式真正的避免了代码的改动了?

没有。在简单工厂模式中,新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色写死(就象上面的例子一样)。而且产品对象创建条件的改变必然会引起工厂角色的修改。

面对这种情况,Java 的反射机制与配置文件的巧妙结合突破了限制——这在Spring 中完美的体现了出来。

小结




1) 当客户程序不需要知道要使用对象的创建过程。

2) 客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。

3.抽象工厂模式

  先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族。
还是让我们用一个例子来形象地说明一下吧。


例子中的NorthFruit 和SouthFruit 就是两个产品树(产品层次结构);而如图所示的
NorthGrape 和NorthPine 就是一个产品族。他们都可以放到水果家族中,因此功能
有所关联。同理SouthGrape 和SouthPine 也是一个产品族。


可以说,抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且
抽象工厂模式是三个里面最为抽象、最具一般性的。
抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象
而且使用抽象工厂模式还要满足一下条件:

1) 系统中有多个产品族,而系统一次只可能消费其中一族产品。

2) 同属于同一个产品族的产品一起使用。

来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):

1) 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须

实现的接口或者必须继承的父类。在java 中它由抽象类或者接口来实现。

2) 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体

产品的对象。在java 中它由具体的类来实现。

3) 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在 java 中一般有抽象类

或者接口来实现。

4) 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在 java 中由具体的类

来实现。


  
  1. //抽象产品角色,具体产品角色与简单工厂模式类似,只是变得复杂了些,这里略。
  2. //抽象工厂角色
  3. public interface AbFruitFactory
  4. {
  5. public Fruit getGrape();
  6. public Fruit getPine();
  7. }

  
  1. public class NorthFruitFactory implements AbFruitFactory
  2. {//具体工厂角色
  3. @Override
  4. public Fruit getGrape()
  5. {
  6. // TODO Auto-generated method stub
  7. return new NorthGrape();
  8. }
  9. @Override
  10. public Fruit getPine()
  11. {
  12. // TODO Auto-generated method stub
  13. return new NorthPine();
  14. }
  15. }

  
  1. public class SouthFruitFactory implements AbFruitFactory
  2. {
  3. @Override
  4. public Fruit getGrape()
  5. {
  6. // TODO Auto-generated method stub
  7. return new SouthGrape();
  8. }
  9. @Override
  10. public Fruit getPine()
  11. {
  12. // TODO Auto-generated method stub
  13. return new SouthPine();
  14. }
  15. }

  
  1. public class MainClass
  2. {
  3. /**
  4. * @param args
  5. * @throws IllegalAccessException
  6. * @throws InstantiationException
  7. */
  8. public static void main(String[] args) throws InstantiationException, IllegalAccessException
  9. {
  10. // TODO Auto-generated method stub
  11. AbFruitFactory Abff_0=new NorthFruitFactory();//抽象工厂方法
  12. Fruit grape_N=Abff_0.getGrape();
  13. grape_N.get();
  14. AbFruitFactory Abff_1=new SouthFruitFactory();
  15. Fruit grape_S=Abff_1.getGrape();
  16. grape_S.get();
  17. Fruit pine_N=Abff_0.getPine();
  18. pine_N.get();
  19. Fruit pine_S=Abff_1.getPine();
  20. pine_S.get();
  21. }
  22. }









文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/9117899

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。