设计模式学习笔记之简单工厂模式

Hellxz博客 Hellxz博客     2022-10-15     218

关键词:

 简介:工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,拒绝客服端程序员通过new创建需要的实例,并且是通过使用一个共同的接口来指向新创建的对象,即接口引用指向实现类对象,是多态的灵活运用。

举例1【未使用工厂模式】:

一个家庭中有多辆汽车,这个家庭想去出游,需要先传一个Car到Family中持有,才能出游。

首先考虑多辆汽车,都有同样的run方法,抽取公共接口如下:

1 package com.mi.simplefactory.simplefactory1;
2 
3 /**
4  * 汽车接口
5  */
6 public interface Car {
7 
8     public void run();
9 }

现在假设有两辆汽车(多辆同理),HondaCar (本田)和 BenzCar(奔驰),都实现了Car接口

 1 package com.mi.simplefactory.simplefactory1;
 2 
 3 public class HondaCar implements Car{
 4 
 5     @Override
 6     public void run() {
 7         System.out.println("本田上路,请勿抛砖");
 8     }
 9 
10     
11 }
 1 package com.mi.simplefactory.simplefactory1;
 2 
 3 public class BenzCar implements Car {
 4 
 5     @Override
 6     public void run() {
 7         System.out.println("奔驰出行,请勿追尾");
 8     }
 9 
10 }

这里需要一个Family类,她应持有一个私有Car的引用,使用Family的构造方法进行初始化Car引用,Family中有一个travel方法

 1 package com.mi.simplefactory.simplefactory1;
 2 
 3 public class Family {
 4 
 5     private Car car;
 6 
 7     public Family(Car car) {
 8         this.car = car;
 9     }
10     public Family() {}
11     public void travel() {
12         System.out.println("全家出游!");
13         car.run();
14         System.out.println("玩的愉快");
15     }
16 }

编写测试类,发现需要通过new 不同的Car实现类实例就可以改变汽车实际类型

 1 package com.mi.simplefactory.simplefactory1;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         /**
 7          * 问题来了:family换个车必须要new不同的车,必须要修改代码,重新编译才能
 8          *                     正确更换汽车,还有,可不可以不用new的方式获取汽车?
 9          */
10 //        Family family = new Family(new HondaCar());
11         Family family = new Family(new BenzCar());
12         family.travel();
13     }
14 }

输出:

先注掉11行,解开10行,运行

全家出游!
本田上路,请勿抛砖
玩的愉快

注掉10,解开11,运行

全家出游!
奔驰出行,请勿追尾
玩的愉快

举例2【分支判断实现工厂】:

这里Car接口和Car接口的实现类不变,重写一个Family类,为car引用设置get set方法,去掉有参构造方法

 1 package com.mi.simplefactory.simplefactory2;
 2 
 3 import com.mi.simplefactory.simplefactory1.Car;
 4 
 5 public class Family {
 6 
 7     private Car car;
 8 
 9     public Family() {}
10     public void travel() {
11         System.out.println("全家出游!");
12         car.run();
13         System.out.println("玩的愉快");
14     }
15     public Car getCar() {
16         return car;
17     }
18     public void setCar(Car car) {
19         this.car = car;
20     }
21     
22     
23 }

创建一个工厂,通过获取汽车的类名为参数,内部if分支判断,实例化内部持有的car引用,还有有一个静态方法getInstance(),获取该 Car的实例

 1 package com.mi.simplefactory.simplefactory2;
 2 
 3 import com.mi.simplefactory.simplefactory1.BenzCar;
 4 import com.mi.simplefactory.simplefactory1.Car;
 5 import com.mi.simplefactory.simplefactory1.HondaCar;
 6 
 7 public class Factory {
 8 
 9     private Car car;
10     public Factory(String carName) {
11         if(carName.equals("BenzCar")) {
12             this.car = new BenzCar();
13         }
14         if(carName.equals("HondaCar")) {
15             this.car = new HondaCar();
16         }
17     }
18     public Car getInstance() {
19         return car;
20     }
21     
22 }

测试类

 1 package com.mi.simplefactory.simplefactory2;
 2 
 3 import com.mi.simplefactory.simplefactory1.Car;
 4 
 5 public class Test {
 6 
 7     public static void main(String[] args) {
 8         /**
 9          * 此包中的factory可以不使用new的方式获取汽车
10          */
11         Family family = new Family();
12 //        Factory factory = new Factory("HondaCar");
13         Factory factory = new Factory("BenzCar");
14         Car car = factory.getInstance();
15         family.setCar(car);
16         family.travel();
17     }
18 
19 }

输出就不贴出来了,和之前的输出是一样的。

这个例子,我们的确通过一个工厂去得到我们需要的实例,但是,如果汽车特别的多,我们是不是需要写无数个分支判断啊?代码很冗长,效率不高,于是我们想到了通过反射来实现,于是有了第三个例子

举例3【通过反射方式】:

学过反射的同学都应该明白,我们可以通过一个properties配置文件去动态改变代码中产生的代码,这是种可以不改变代码的情况下使用的很方便的方式

创建一个properties配置文件:config.properties,(这里直接写好了两个,方便切换)

#Car=com.mi.simplefactory.simplefactory1.BenzCar
Car=com.mi.simplefactory.simplefactory1.HondaCar

创建Factory类

 1 package com.mi.simplefactory.simplefactory3;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.util.Properties;
 6 
 7 import com.mi.simplefactory.simplefactory1.Car;
 8 
 9 public class Factory {
10 
11     private Factory() {} //拒绝客服端程序员new工厂对象,仅提供静态方式访问
12     public static Properties configs = new Properties();
13     static {
14         //获取配置文件流
15         InputStream in = Factory.class.getResourceAsStream("config.properties");
16         try {
17             //properties读取文件输入流
18             configs.load(in);
19         } catch (IOException e) {
20             e.printStackTrace();
21             //静态方法/块中的异常是捕获不到的
22             throw new RuntimeException(e);
23         }
24     }
25     public static Car getInstance() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
26         //从配置文件中取出Car键的值:汽车类的全路径
27         String carName = configs.getProperty("Car");
28         //反射获取Class对象
29         Class<?> clazz = Class.forName(carName);
30         //反射新建实例
31         Car car = (Car)clazz.newInstance();
32         return car;
33     }
34     
35 }

以上代码是在这个Factory类被ClassLoader load的时候自动读取配置文件,并在配置文件中get(key)的方式获得key对应的value,查看Java docs文档可以看出Properties类是一种Map的实现,通过forName反射出我们需要的类的Class对象(在文件中查找我们需要的 类.class 文件),通过newInstance()方法获取该类的实例,相当于new,这样我们就能动态的通过修改配置文件,而无需修改代码,无需重新编译即可改变代码中的对象。

下边是测试类

 1 package com.mi.simplefactory.simplefactory3;
 2 
 3 import com.mi.simplefactory.simplefactory1.Car;
 4 import com.mi.simplefactory.simplefactory2.Family;
 5 
 6 public class Test {
 7 
 8     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
 9         Family family = new Family();
10         Car car = Factory.getInstance();
11         family.setCar(car);
12         family.travel();
13     }
14 }

输出:

打开配置文件第一行,关掉第二行

全家出游!
奔驰出行,请勿追尾
玩的愉快

打开配置文件第二行,关掉第一行

全家出游!
本田上路,请勿抛砖
玩的愉快

 

总结:

  简单工厂模式:

  1. 私有化工厂类的构造方法
  2. 根据配置文件的变化或者传参的变化,动态返回一个该参数代表的类的实例
  3. 拥有一个getInstance的方法

设计模式学习笔记--简单工厂模式和工厂模式

老生长谈的两个设计模式了,这里把这两个设计模式对比着来总结一下。什么是简单工厂模式?简单工厂模式:根据传入工厂类的参数动态决定要创建哪一个产品类的实例。UML图如下(以实现一个计算器为例):   &nb... 查看详情

《设计模式》学习笔记2——简单工厂模式

定义简单工厂模式并不属于GoF(GangofFour四人组)23中设计模式,有些地方的解释说因为简单工厂模式太简单,所以23中设计模式就没有单独列出。但是简单工厂模式在实际的应用中却很常用,因此在刘伟老师的《设计模式》一书... 查看详情

java学习笔记-----设计模式之工厂模式

1.设计模式---------->工厂模式:Sender.javapackage me.ele.mytest;public interface Sender{   public void send();} 2.MailSendpackage me.ele.mytest;public  查看详情

设计模式学习笔记之抽象工厂模式

简介:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。举例:每个汽车4s店和某个品牌工厂之间的关系,每个汽车4s店只会卖同一品牌的汽车,但是如果这一品牌汽车销量不好,效益不... 查看详情

设计模式二(简单工厂模式)

学习笔记之设计模式二,简单工厂;假设要取得数据库连接字符串,1.创建抽象类:publicabstractclassConnectString{//输出字符串publicabstractstringGetConnectString();}2.创建各个实体类:publicclassSqlConnectString:ConnectString{publicoverridestringGetConnect 查看详情

工厂模式学习笔记(代码片段)

人类工业进化史与java设计模式石器时代:newObject();小作坊模式:简单工厂模式小工厂:工厂方法模式流水线大厂:抽象工厂模式简单工厂注:下面都会以手机厂商举例来理解各个设计模式,全部代码会在最后提供下载地址首先需... 查看详情

《大话设计模式》学习笔记系列--1.简单工厂模式

...;  简单工厂模式实现了一种"工厂"概念的面向对象设计模式,它可以在不指定对象具体类型的情况下创建对象。其实质是定义一个创建对象的接口,但让实现这个接口的类来决定实例化具体类。工厂方法让类的实例化推迟... 查看详情

工厂模式&抽象工厂——headfirst设计模式学习笔记

...继承改变创建方法行为。简单工厂:简单工厂并不是一种设计模式,因为只是简单的把创建对象的代码封装起来工厂模式:在父类定义了一个创建对象的接口,通 查看详情

学习笔记之工厂模式-2017年1月11日23:00:53

  当做日记流水来写吧。今天看的工厂模式和抽象工厂。设计原则:依赖倒置原则:不依赖具体类,依赖抽象。工厂方法模式:定义了一个创建对象的接口,但由子类来决定要实例化的类是哪一个。工厂方法让类吧实例化推迟... 查看详情

java设计模式学习笔记,二:工厂模式

  工厂模式,主要实现了创建者和调用者的分离。  分类:1、简单工厂模式;2、工厂方法模式;3、抽象工厂模式。  核心:实例化对象时,用工厂方法代替new操作。   一、简单工厂模式    也叫静态工厂模式... 查看详情

设计模式之简单工厂模式(代码片段)

    今天学习了简单工厂模式,总结一下。    简单工厂模式的核心思想是:由一个工厂实体决定创建出哪一种产品的实例。    比较简单,因此直接上代码:  这个例子我们实现一个简单的计算器。我们先... 查看详情

设计模式学习笔记——简单工厂模式(代码片段)

说明(2018-4-320:25:16):1.数据结构看到了树,好像后面的都是伪代码了,感觉暂时用不上。另外还有一个队列的实现没有敲代码,不过目前已经对指针有了一个深刻的了解了。准备先放一放数据结构,开始C#的继续深入。2.其实... 查看详情

java设计模式之二-----工厂模式

...了单例模式创建的几种方法以及最优的方法。本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式、工厂方法和抽象工厂模式。简单工厂模式简单工厂模式是属于创建型模式,又叫做静态工厂方法模式。简单工厂模式是由... 查看详情

大话设计模式之简单工厂模式

简单工厂模式  最近朋友推荐了一本书《大话设计模式》,此书刚刚到,博主也还没开始看,希望以博文的方式与大家一起分享,一起学习.简单工厂模式,也就是说,到底要实列化谁,将来会不会增加实列化的对象,比如增加开根运算,... 查看详情

工厂三兄弟之简单工厂模式

...工厂模式概述      简单工厂模式并不属于GoF23个经典设计模式,但通常将它作为学习其他工厂模式的基础,它的设计思想很简单,其基本流程如下:      首先将需要创建的各种不同对象(例如各种不同... 查看详情

java进阶篇设计模式之二-----工厂模式

...了单例模式创建的几种方法以及最优的方法。本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式、工厂方法和抽象工厂模式。简单工厂模式简单工厂模式是属于创建型模式,又叫做静态工厂方法模式。简单工厂模式是由... 查看详情

设计模式:简单工厂工厂方法抽象工厂之小结与区别

简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。本文是本人对这三种模式学习后的一个小结以及对他们... 查看详情

设计模式笔记1:简单工厂模式

...好处  通过封装、继承多态把程序的耦合度降低,使用设计模式使得程序更加灵活,容易修改,易于复用。 1.2 类图   1.3代码几个运算类; ViewCode 工厂代码:  ViewCode& 查看详情