设计模式之工厂模式

前言

	设计模式一直都是我们程序语言中较为重要的代码优化套路
为了减少一些冗余代码,提高代码可复用性、可维护性、可读性、稳健性以及安全性。
设计是一种语法规范,是一种为了解决某种特点场景下的某个问题,而提出来的一系列方案。
设计模式一共分为23种,其中分为三种大类型;而我们今天所有讲的是创造型中的工厂模式

工厂模式分类

	工厂模式中分了三种
	 1.简单工厂
	 2.工厂方法
	 3.抽像工厂
	 我们在了解工厂模式中需要知道的角色划分
	 1.抽像产品:被产品类实现的抽像接口
	 2.具体产品:定义的具体产品类
	 3.产品簇:一个工厂中相互具有联系的多种产品
	 4.产品等级:相同种类不同品牌的产品

场景介绍

    本博文以电脑中的不同品牌进行不同场景间的叙述
    
   首先在 服务人员进行卖电脑业务(以华硕和战神电脑进行讲解)
   
   客户进行买电脑业务,在不使用设计模式下的代码实现
1.先定义一个抽像产品接口

interface  Computer{
    Computer getComputer();
}
2.创建具体产品类
//创建一个具体产品类
class  AsusComputer implements Computer{
    @Override
    public  Computer getComputer(); {
        return new AsusComputer ();
    }
}
3.进行测试
public class Client {
    public static void main(String[] args) {
        /**  
	         缺点 1.存在耦合性
	              2.违反了迪米特原则,当客户应该只知道我们提供的接口,而不应该直接访问具体类
	              
	        在不使用设计模式下的代码实现,我们不难发现  AsusComputer与客户类存在耦合性
            当服务端修改具体产品类的名称的时候,客户类也必须修改,否则就会编译报错
         */
        Computerfood = new AsusComputer();//简单的完成了一个买电脑的过程

    }
}
进行简单工厂模式的改良
1. 创建一个抽像产品接口
interface  Computer{
    void getComputer();
}
2. 创建一个具体产品类

class MarsComputer implements Computer{

    @Override
    public void getComputer() {
        System.out.println("战神电脑");
    }
}
3. 创建一个具体产品类
class  AsusComputer implements Computer{

    @Override
    public void getComputer() {
        System.out.println("华硕电脑");
    }
}

//创建一个电脑工厂类
class ComputerFactory {
    static Computer electric = null;

    public static Computer getElectric(String type) {
          switch (type){
              case "战神":
                  electric =new MarsComputer();
                  break;
              case "华硕":
                  electric=  new AsusComputer();
                  break;
          }
          return electric;

    }
}
//进行测试
public class Client {
    public static void main(String[] args) {
        Computer electric =ComputerFactory.getElectric("战神");
        electric.getComputer();
    }
}

  这是使用了简单工厂模式之后的代码改良
  区别:简单工厂模式比不使用设计模式多个一个工厂的具体类,我们将创建电脑业务直接方法工厂中,而不是直接客户进行访问
  好处:1.具体电脑类与客户类进行了解耦
       2.如果当我们在服务端修改了电脑类的类名,客户端不需要进行改变,客户端也不知道,所以遵守了迪米特  	
          法则
 缺点:我们当前业务中值存在战神电脑和华硕电脑,那么如果接下来如果我想要拓展其他品牌的电脑业务的时候
        我需要去修改ComputerFactory 工厂类中的switch,这显然是不合理的
        为什么? 这样子违反了设计原则中的开闭原则(对扩展开放,对修改关闭),我们在每次新增
        业务的时候都需要去修改源码...      
进行工厂方法模式的改良
//创建一个抽像产品接口
interface  Computer{
    void getComputer();
}
//创建工厂接口
interface  ComputerFactory{
    Computer getComputer();
}
//创建具体工厂
class AsusComputerFactory implements ComputerFactory{

    @Override
    public Computer getComputer() {
        return new AsusComputer();
    }
}
//创建具体工厂
class MarsComputerFactory implements ComputerFactory{

    @Override
    public Computer getComputer() {
        return new MarsComputer();
    }
}
//创建一个具体产品类
class  MarsComputer implements Computer {

    @Override
    public void getComputer() {
        System.out.println("战神电脑");
    }

}
//创建一个具体产品类
class  AsusComputer implements Computer {

    @Override
    public void getComputer() {
        System.out.println("华硕电脑");

    }

}
public class Client {
    public static void main(String[] args) {
        ComputerFactory computerFactory = new MarsComputerFactory();
        Computer electric =computerFactory.getElectric();
        electric.getComputer();
    }
}
  以上代码是经过工厂方法模式的代码改良
    工厂模式与简单工厂模式的区别
    1.我们不难发现简单工厂模式的工厂类他需要进行多个业务判断,导致一个工厂生成多个产品;
    而工厂模式中每一个品牌电脑类对应一个品牌工厂类,一个工厂类只负责生产一个对应的产品,
    
    优点:
    1. 可扩展性,使用工厂模式之后当我们需要扩展其他品牌的电脑的时候,只需要实现工厂接口
    并创建对应的品牌产品类,无需修改到源代码
    2. 延续了简单工厂的好处
        
    缺点: 试想一下如果现在电脑城引进了新产品,电视机,那么我们需要编写几个类?
          首先定义电视机接口,创建对应品牌的电视机,
          其次定义电视机工厂接口,创建对应品牌的电视机工厂(场景中只有两个品牌,需要创建4个类)
    		那么问题来了,如果随着品牌的增加,那么在新增其他电子产品的时候,所需要创建的类是需要非常多的
    		那么在这个时候,我们就需要使用抽像方法模式
    
进行抽像工厂模式的改良
//创建一个抽像产品接口
interface  Computer{
    void getComputer();
}
//创建一个抽像产品接口
interface  Tv{
    void getTv();
}

//创建工厂接口
interface  Factory{
    //生产电脑
    Computer getElectric();
    //生产电视
    Tv getTv();
}

//创建具体工厂
class AsusComputerFactory implements Factory {

    @Override
    public Computer getElectric() {
        return new AsusComputer();
    }

    @Override
    public Tv getTv() {
        return new AsusTv();
    }
}

//创建具体工厂
class MarsComputerFactory implements Factory {

    @Override
    public Computer getElectric() {
        return new MarsComputer();
    }

    @Override
    public Tv getTv() {
        return new MarsTv();
    }
    //一个工厂中两个产品相互之间有联系的产品称为产品簇
}

//创建一个具体产品类
class  MarsComputer implements Computer {

    @Override
    public void getComputer() {
        System.out.println("战神电脑");
    }

}

//创建一个具体产品类
class  AsusComputer implements Computer {

    @Override
    public void getComputer() {
        System.out.println("华硕电脑");

    }

}
//创建一个具体产品类
class  MarsTv implements Tv {

    @Override
    public void getTv() {
        System.out.println("战神tv");
    }
}

//创建一个具体产品类
class  AsusTv implements Tv {

    @Override
    public void getTv() {
        System.out.println("华硕tv");
    }

}
public class Client {
    public static void main(String[] args) {
        Factory computerFactory = new MarsComputerFactory();
        Computer electric =computerFactory.getElectric();
        Tv tv = computerFactory.getTv();
        tv.getTv();
        electric.getComputer();



    }
}
以上代码是进过抽像工厂模式的改良  
抽像工厂模式和工厂方法模式的区别
     注意:抽像工厂模式只是将工厂接口定义的范围更抽像化了
		     我在抽像工厂模式中定义的工厂接口为factory(其中可以生成多种产品),
		     在工厂模式中定义的接口为    ComputerFactory(只能生成一种产品)
      在上面代码中我们可以发现,每一个品牌工厂都可以生成电视机和电脑,这个无疑减免了两个工厂类的创建
      ***我们将同一个工厂下生成的多个不同类型单相互之间存在联系的产品称为产品簇***
      在上述代码中同一个工厂下的电脑和电视机我们就称为是同一个产品簇

缺点:当产品等级(我们将不同工厂下的同一个产品类型称为一个产品等级)
      新增之后我们就需要在工厂接口中去定义新的产品获取方法,这样的话,实现工厂接口的工厂类
      又需要修改大量代码,又违反了开闭原则
使用场景介绍
我们可以发现其实每一个设计模式中都存在一些问题,但是提供这些设计模式只是在不同场景下做出的权衡
也就是说工厂模式下的三种模式,我们需要在特点的场景中来选择使用哪一种设计模式

简单工厂模式:当明确的知道具体产品且产品不会发生扩展的情况下可以使用简单工厂模式(不会违反开闭原则)
工厂工厂模式:当产品等级只有一个的情况下(每个工厂中只生成一个产品),可以使用工厂方法模式
抽像工厂模式:当产品等级存在多个且明确知道产品等级不会发生变化的时候,就可以使用抽像工厂模式
否则不建议使用工厂模式

以上呢就是工厂模式的介绍啦,觉得博主写的有问题或者想要交流的童鞋们,可以评论与博主进行交流
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值