经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
java设计模式--三种工厂模式详解
来源:jb51  时间:2021/7/19 19:54:19  对本文有异议

简单工厂

简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)。当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式。

由于创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法模式(Static Factory Method)。

在这里插入图片描述

  • Product表示产品接口,也可用抽象类实现,封装产品间共有的属性。
  • ConcreteProduct*表示具体的实际产品。
  • Factory表示工厂,工厂根据需要来创建相应的产品。

这样一来,当添加新的产品C时,只需要修改工厂部分代码即可,而传统方法需要在每一个创建产品的地方都进行修改。可以理解为把具体的产品创建封装成一个工厂类。

举个例子,大富翁的地图创建:

  • AbstractBlock是接口,表示抽象的地块,包括方法printBlock()打印地块。
  • Empty、Prison、Park实现上述接口,表示空地(*)、监狱(&)和公园(#)。
  • SimpleFactory是创建地块的简单工厂。

类图:

在这里插入图片描述

代码:

1.产品接口

  1. public interface AbstractBlock {
  2. public void printBlock();
  3. }

2.产品接口实现子类

  1. public class Empty implements AbstractBlock{
  2. @Override
  3. public void printBlock() {
  4. System.out.print("* ");
  5. }
  6. }
  1. public class Park implements AbstractBlock{
  2. @Override
  3. public void printBlock() {
  4. System.out.print("# ");
  5. }
  6. }
  1. public class Prison implements AbstractBlock{
  2. @Override
  3. public void printBlock() {
  4. System.out.print("& ");
  5. }
  6. }

3.简单工厂类

  1. public class SimpleFactory {
  2. public AbstractBlock getBlock(String type){ //根据传参创建不同的地块
  3. if(type.equalsIgnoreCase("Empty")){
  4. return new Empty();
  5. } else if(type.equalsIgnoreCase("Park")){
  6. return new Park();
  7. } else if(type.equalsIgnoreCase("Prison")){
  8. return new Prison();
  9. }
  10. return null;
  11. }
  12. }

4.调用工厂

  1. public class Map {
  2. public void getMap(){
  3. SimpleFactory simpleFactory=new SimpleFactory(); //实例化工厂
  4. ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>(); //地块集合
  5. String []types=new String[3];
  6. types[0]="Empty";
  7. types[1]="park";
  8. types[2]="Prison";
  9. Random rd = new Random();
  10. for(int i=1;i<=12;i++){ //随机用工厂创建地块并放入集合
  11. int tt = rd.nextInt(types.length);
  12. map.add(simpleFactory.getBlock(types[tt]));
  13. }
  14. //地图大小写死了,不是重点
  15. for(int i=0;i<12;i++){
  16. map.get(i).printBlock();
  17. if(i==3||i==5||i==7)
  18. System.out.println();
  19. if(i==4||i==6)
  20. System.out.print(" ");
  21. }
  22. }
  23. }

5.测试

  1. public class MonoPoly {
  2. public static void main(String[] args) {
  3. Map map=new Map();
  4. map.getMap();
  5. }
  6. }

运行结果

在这里插入图片描述

工厂方法

不难发现,当增加新的产品时需要对简单工厂类修改,或创建多个简单工厂。(比如增加一个法院地块)工厂方法进一步解耦合,把工厂类抽象,不再负责所有实例的创建,而是把具体的创建工作交给了子类去完成,实例化延迟到子类加载,由子类来决定要实例化的类。

在这里插入图片描述

抽象化工厂类,把具体实例化工作交给其子类实现。

代码:

1.工厂接口

  1. public interface AbstractFactory {
  2. public AbstractBlock createBlock();
  3. }

2.工厂实现子类

  1. public class EmptyFactory implements AbstractFactory {
  2. @Override
  3. public AbstractBlock createBlock() {
  4. return new Empty();
  5. }
  6. }
  1. public class ParkFactory implements AbstractFactory {
  2. @Override
  3. public AbstractBlock createBlock() {
  4. return new Park();
  5. }
  6. }
  1. public class PrisonFactory implements AbstractFactory {
  2. @Override
  3. public AbstractBlock createBlock() {
  4. return new Prison();
  5. }
  6. }

3.产品接口

  1. public interface AbstractBlock {
  2. public void printBlock();
  3. }

4.产品实现子类

  1. public class Empty implements AbstractBlock {
  2. @Override
  3. public void printBlock() {
  4. System.out.print("* ");
  5. }
  6. }
  1. public class Park implements AbstractBlock {
  2. @Override
  3. public void printBlock() {
  4. System.out.print("# ");
  5. }
  6. }
  1. public class Prison implements AbstractBlock {
  2. @Override
  3. public void printBlock() {
  4. System.out.print("& ");
  5. }
  6. }

5.调用

  1. public class Map {
  2. public void getMap() {
  3. ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>(); //地块集合
  4. AbstractFactory abstractFactory;
  5. Random rd = new Random();
  6. for(int i=1;i<=12;i++){ //随机用工厂创建地块并放入集合
  7. int tt = rd.nextInt(3);
  8. if(tt==0)abstractFactory=new EmptyFactory();
  9. else if(tt==1)abstractFactory=new ParkFactory();
  10. else abstractFactory=new PrisonFactory();
  11. map.add(abstractFactory.createBlock());
  12. }
  13. //地图大小写死了,不是重点
  14. for(int i=0;i<12;i++){
  15. map.get(i).printBlock();
  16. if(i==3||i==5||i==7)
  17. System.out.println();
  18. if(i==4||i==6)
  19. System.out.print(" ");
  20. }
  21. }
  22. }

6.测试

  1. public class MonoPoly {
  2. public static void main(String[] args) {
  3. Map map=new Map();
  4. map.getMap();
  5. }
  6. }

运行结果:

在这里插入图片描述

抽象工厂

不难发现当创建新的产品接口时,也需要对工厂方法修改,或创建多个工厂方法。(比如增加魔法地块簇,对应组产品魔法公园、魔法空地、魔法监狱等)

抽象工厂将工厂方法进一步抽象。定义了一个接口用于创建相关或有依赖关系的对象簇,而无需指明具体的类。可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

在这里插入图片描述

把工厂类抽象后,对应不同子类工厂(普通/魔法),生产对应的一组产品。最后调用时统一调用抽象接口即可,不必知道具体对象,面向接口编程。

1.产品接口

  1. public interface AbstractBlock {
  2. void printBlock();
  3. }

2.产品抽象子类-普通产品

  1. public abstract class NormalAbstractBlock implements AbstractBlock {
  2. public abstract void printBlock();
  3. }

2.2普通空地

  1. public class NormalEmpty extends NormalAbstractBlock {
  2. public void printBlock() {
  3. System.out.print("* ");
  4. }
  5. }

2.3普通公园

  1. public class NormalPark extends NormalAbstractBlock {
  2. public void printBlock() {
  3. System.out.print("# ");
  4. }
  5. }

2.4普通监狱

  1. public class NormalPrison extends NormalAbstractBlock {
  2. public void printBlock() {
  3. System.out.print("& ");
  4. }
  5. }

3.1产品抽象子类-魔法产品

  1. public abstract class MagicAbstractBlock implements AbstractBlock {
  2. public abstract void printBlock();
  3. }

3.2魔法空地

  1. public class MagicEmpty extends MagicAbstractBlock {
  2. public void printBlock() {
  3. System.out.print("e ");
  4. }
  5. }

3.3魔法公园

  1. public class MagicPark extends MagicAbstractBlock {
  2. public void printBlock() {
  3. System.out.print("g ");
  4. }
  5. }

3.4魔法监狱

  1. public class MagicPrison extends MagicAbstractBlock {
  2. public void printBlock() {
  3. System.out.print("p ");
  4. }
  5. }

4.工厂接口

  1. public interface AbstractFactory {
  2. AbstractBlock getEmpty();
  3. AbstractBlock getPrison();
  4. AbstractBlock getPark();
  5. }

5.工厂实现子类-普通工厂

  1. public class NormalFactory implements AbstractFactory {
  2. public AbstractBlock getEmpty() { return new NormalEmpty(); }
  3. public AbstractBlock getPrison() { return new NormalPrison(); }
  4. public AbstractBlock getPark() { return new NormalPark(); }
  5. }

6.工厂实现子类-魔法工厂

  1. public class MagicFactory implements AbstractFactory {
  2. public AbstractBlock getEmpty() { return new MagicEmpty(); }
  3. public AbstractBlock getPrison() {return new MagicPrison(); }
  4. public AbstractBlock getPark() { return new MagicPark(); }
  5. }

7.调用

  1. public class Map {
  2. public void getMap(AbstractFactory af){
  3. ArrayList<AbstractBlock> map=new ArrayList<AbstractBlock>();
  4. map.add(af.getEmpty());
  5. map.add(af.getPrison());
  6. map.add(af.getPark());
  7. Random rd = new Random(3);
  8. int col=12;
  9. for(int i=1;i<=col;i++){
  10. int tt = rd.nextInt(3);
  11. map.get(tt).printBlock();
  12. if(i==4||i==6||i==8)
  13. System.out.println();
  14. if(i==5||i==7)
  15. System.out.print(" ");
  16. }
  17. }
  18. }

8.测试

  1. public class Monopoly {
  2. public void play(){
  3. Map map=new Map();
  4. Scanner scan = new Scanner(System.in);
  5. System.out.println("请输入指令(1输出普通地图,2输出魔法地图)");
  6. int order;
  7. order = scan.nextInt();
  8. if(order == 1){
  9. map.getMap(new NormalFactory());
  10. }else{
  11. map.getMap(new MagicFactory());
  12. }
  13. }
  14. }

运行结果:

在这里插入图片描述

在这里插入图片描述

总结

本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注w3xue的更多内容!

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

本站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号