创建型模式之抽象工厂模式

抽象工厂模式

先说一个场景:大学的时候,为了打游戏打的爽,买现成的电脑不是CPU不满意就是内存堪忧,那怎么办呢?组装电脑呗,把自己想要CPU,主板,内存,硬盘等配件搞来组装

但这样有一系列的问题,比如选择CPU的时候,只有把品牌,型号,主频等确定下来,才能确定具体的CPU,同样的问题也发生在主板上

最后还有配件的兼容性,不能说买最好的CPU和主板搭配在一起,肯定好使.如果CPU针脚数和主板提供的CPU插口不兼容,是无法组装的.

那么这样就可以得出一个结论:装机方案是有整体性的,里面选择的各个配件之间是有联系的

下面组装过程只考虑CPU和主板

因此当装机师为不同的客户组装电脑时,只需要按照客户的装机方案(方案已确定),去获取相应的配件,然后组装就可以了

那么如何用程序来实现这个过程呢?

不用模式的解决方案

考虑客户的功能,需要选择自己需要的CPU和主板,然后告诉装机师自己的选择,接下来就是装机师组装机器了
对于装机师来说,只是知道CPU和主板的接口,而不知道具体实现,很明显可以使用简单工厂模式

下面来撸代码:

  • CPU和主板的接口(父类):
 class CPU
 {
   //运算
   public void calculate()
  }
  class MainBoard
  {
    //安装CPU
    public void  installCPU()
  }
  • 具体的CPU实现
class IntelCPU : CPU 
  {
    //针脚数
    int pins = 0
    intelCPU(int pins) 
    {
      self.pins = pins
    }
    public void calculate()
    {
       print("现在使用的是intel CPU,pins="+pins)
    }
  }
  
  class AMDCPU : CPU 
  {
       //针脚数
    int pins = 0
    intelCPU(int pins) 
    {
      self.pins = pins
    }
    public void calculate()
    {
       print("现在使用的是锐龙 CPU,pins="+pins)
    }
  }
  • 具体的主板实现
 public class IntelMainboard implements MainBoard {  
      //CPU插槽的孔数  
      private int cpuHoles = 0;  
      public GAMainboard(int cpuHoles){  
          this.cpuHoles = cpuHoles;  
      }  
      public void installCPU() {  
          print("now in IntelMainboard,cpuHoles=" + cpuHoles);  
      }  
 } 
 
 public class AMDMainboard implements MainBoard{  
       //CPU插槽的孔数 
      private int cpuHoles = 0;  
      public AMDMainboard(int cpuHoles){  
          this.cpuHoles = cpuHoles;  
      }  
      public void installCPU() {  
          print("now in AMDMainboard,cpuHoles=" + cpuHoles);  
      }
} 
  • 创建CPU和主板的工厂
 public class CPUFactory {  
       createCPU(int type){  
          CPU cpu = null;  
          //根据参数来选择并创建相应的CPU对象  
          if(type==1){  
              cpu = new IntelCPU(100);  
          }else if(type==2){  
              cpu = new AMDCPU(200);  
          }  
          return cpu;  
      }    
 } 
 public class MainboardFactory {   
        createMainboard(int type){  
          MainboardApi mainboard = null;  
          //根据参数来选择并创建相应的主板对象  
          if(type==1){  
              mainboard = new IntelMainboard(100);  
          }else if(type==2){  
              mainboard = new AMDMainboard(200);  
          }  
          return mainboard;  
      }  
}
  • 装机
  -(void)createComputer(int cpuType, int mainBoardType){
    CPU *cpu = [CPUFactory createCPUWithType:cpuType];
    MainBoard *mainBoard = [MainBoardFactory  createMainBoardWithType:mainBoardType];
    [cpu calculate];
    [mainBoard installCPU];
}
  • 客户端调用
ComputerEngineer *eng = [ComputerEngineer new];
eng.createComputer(1,1);

上面的代码完美实现了装机过程,只知CPU和主板的接口,不知道具体的实现,但大家会发现有个问题?CPU和主板是有联系的,需要匹配,但上面的实现并没有维护这种关系

如何解决问题呢?抽象工厂模式

抽象工厂模式来解决

定义: 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类

分析上面的问题,和抽象工厂模式的定义得出两个要点:

  • 只知道所需要的一系列对象的接口,而不知道具体实现
  • 一系列对象是相关或者相互依赖的

看到这肯定会有人在想只知接口不知具体实现不是简单工厂模式吗?这里强调一下抽象工厂模式和简单工厂模式的区别:简单工厂模式关注的是单个产品对象的创建,比如创建CPU的工厂方法,只关心如何创建CPU对象,而创建主板的工厂方法,就只关心如何创建主板对象.抽象工厂模式要创建的是一系列的产品对象,而且这一系列对象是构成新对象所需要的组成部分,也就是这一系列被创建的对象相互之间是有约束的

那么抽象工厂模式是怎么解决问题的呢?
在抽象模式里面,会定义一个抽象工厂,在里面虚拟的创建客户端需要的这一系列对象.这里的虚拟就是定义创建这些对象的抽象方法,并不去真的实现,然后由具体的抽象工厂的子类来提供这一系列对象的创建,这样一来可以为同一抽象工厂提供很多不同的实现,那么创建的这一系列对象也就不一样了,也就是说,抽象工厂在这里起到一个约束左右,并提供所有子类的一个统一外观,来让客户端使用

模式结构

AbstractFactory:抽象工厂,定义创建一系列产品对象的操作接口。
ConcreteFactory:具体的工厂,实现抽象工厂定义的方法,具体实现一系列产品对象的创建。
AbstractProduct:定义一类产品对象的接口。
ConcreteProduct:具体的产品实现对象,通常在具体工厂里面,会选择具体的产品实现对象,来创建符合抽象工厂定义的方法返回的产品类型的对象。
Client:客户端,主要使用抽象工厂来获取一系列所需要的产品对象,然后面向这些产品对象的接口编程,以实现需要的功能。

重写示例

  • 具体的CPU和主板类不变
  • 抽象工厂
 class AbFactory:
 {
   -(CPU *)createCPU;
   -(MainBoard *)createMainBoard;
 }
  • 具体工厂类
 class IntelFactory : AbFactory
 - (CPU *)createCPU
{
    return [IntelCPU createCPUWithPins:100];
}

- (MainBoard *)createMainBoard
{
    return [IntelMainBoard createMainBoardWithCpuHoles:100];
}

 class AMDFactory : AbFactory
- (CPU *)createCPU
{
    return [AMDCPU createCPUWithPins:200];
}

- (MainBoard *)createMainBoard
{
    return [AMDMainBoard createMainBoardWithCpuHoles:200];
}
  • 装机师装机
class computerEngineer:
- (void)makeComputer:(AbFactory *)factory
{
    CPU *cpu = [factory createCPU];
    MainBoard *mainBoard = [factory createMainBoard];
    [cpu calculate];
    [mainBoard installCPU];
}

抽象工厂模式的优缺点

优点:

  • 降低耦合性

    抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样就将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而降低系统耦合性

  • 符合开-闭原则

    新增一种产品类时,只需要添加相应的具体产品类和相应的工厂子类即可

缺点

很难支持新种类产品的变化,如果添加了新种类,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类以及所有子类的改变,违背了"开发-封闭"原则

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值