静态工厂 java_Java学习笔记(十四)——Java静态工厂

【前面的话】

每天过的还行,对我来说,只要让自己充实,生活就会是好的。

学习Java工场方法的原因是最近在使用Spring框架做一个系统,其中有一个注入的方法是使用静态工场方法注入,所以学习一下,基础性文章,选择性阅读。

这篇文章学习的是静态工厂。

【什么是】

一、定义

:在面向对象程序设计中,工厂通常是一个用来创建其他对象的对象。工厂是构造方法的抽象,用来实现不同的分配方案。

二、举例

工厂模式是根据不同的参数创建对象。例如用工厂创建小汽车。 如果我们想要一辆奥迪,工厂就会为我们生产一辆奥迪;如果我们需要一辆宝马,工厂则会为我们生产一辆宝马。工厂会根据不同的参数,为我们提供不同的物品。而这些创建的过程就是实例化,也就是是说,对对象实例化的过程封装起来,专门建立一个类进行实例化,这就是工厂模式。

【怎么做】

从下面两段关键代码来看,没有使用静态工厂的代码使得Manager类和具体的实现类紧耦合,如果生产的汽车种类繁多的话,Manager会经常变化,使得Manager类会经常修改,而使用了静态工厂的代码,将所有的实例化都封装在一个工厂类中,以后可能不光是Manager这个类可以调用工厂类,增加的别的方法也是可以调用工厂了。

一、没有使用静态工厂的代码:

1. Manager.java

1 public classManager {2 public staticCar CreatCar(String type){3 Car car = null;//Manager与Audi类和BaoMa类还有Suv类耦合,进行了硬编码

4 if(type.equals("audi")){5 car=newAuDi();6 }else if(type.equals("baoma")){7 car=newBaoMa();8 }else if(type.equals("suv")){9 car=newSuv();10 }11 car.Prepare();12 car.Install();13 car.Color();14 returncar;15 }16 }

二、使用静态工厂的代码:

1. Manager.java

1 public classManager {2 Car car = null;3 public Car CreatCar(String type){//Manager类和具体类解耦合,不需要关心具体的类的实现方法。

4 car=CarFactory.getCarInstance(type);//静态方法,不需要使用创建工厂CarFactory来创建对象,直接使用CarFactory来调用其方法。

5 car.Prepare();6 car.Install();7 car.Color();8 returncar;9 }10 }

2. CarFactory.java

1 public classCarFactory {2 public static Car getCarInstance(String type){//静态方法,这样做的缺点是如果CarFactory被继承,getCar不能被重写。

3 Car carInstance = null;4 if(type.equals("audi")){5 carInstance=newAuDi();6 }else if(type.equals("baoma")){7 carInstance=newBaoMa();8 }else if(type.equals("suv")){9 carInstance=newSuv();10 }11 returncarInstance;12 }13 }

【为什么】

为什么要使用静态工厂模式,这样做的好处如下几点:

第一:静态工厂方法可以突破构造函数不能自由命名的限制,对于不同的工厂方法可以采用不同的会意的名字,是程序具有更好的可读性。JAVA平台库的java.text.Format的子类NumberFormat就有getInstance() , getPrecentInstance() , getCurrencyInstatnce()等静态方法,通过不同的名字产生特定的对象。

第二:静态工厂方法是用来产生对象用的,至于产生什么类型的对象没有限制,这就意味这只要返回原返回类型或原返回类型的子类型都可以,这样就加大了程序设计和使用的灵活行,如java.util集合框架就采用了这种优势,这样就可以更好达到封装的目的,降低API的数目和用户的使用难度,java.util.Connections是集合框架的辅助类用于对原有的集合类进行进一步封装,产生一些同步的集合,不可修改的视图。都是采用静态工厂方法实现的,至于方法内部的实现类就完全别封装了。也迫使我们使用接口编程。

第三:静态工厂方法所创建的对象可以在编译时不存在,动态创建对象,采用放射,类似SPRING的IOC容器方转。最典型的例子就是spi服务提供者框架,Service Provider Iframe 是一种用于在运行时刻产生对象的框架,达到对象的创建与使用分离,是对象的客户和对象之间解耦,增加程序的灵活性和可扩展性。既然spi可以动态创建对象,那么采用什么机制来创建什么对象,创建对象的依据是什么了,spi必须一种统一的注册机制,对于要创建的对象,应该在XML文件中配置,到时候,只要提供一个字符串,就可以凭借该字符串来创建配置的对象

【缺点】

静态方法,这样做的缺点是如果CarFactory被继承,getCar不能被重写。

因为我们一般都采用的是构造函数进行实例化对象,而采用静态工厂的方法进行实例化就会使得实例化和构造函数实例化不一样,所以增加了使用难度,一般都要采用较为清晰的命名,使得使用者可以一目了然知道使用了静态方法。

如果例子中某一个具体类的构造函数式私有,就会出现错误。

【代码举例】

下面记录了两个代码demo,一个是没有使用静态工厂方法的demo,一个是使用了静态工厂方法的demo。

一、不是用静态工厂模式的代码

1. AuDi.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public class AuDi implementsCar {2 public voidPrepare(){3 System.out.println("我是奥迪车,我在进行生产准备");4 }5 public voidInstall(){6 System.out.println("我是奥迪车,我在进行组装");7 }8 public voidColor(){9 System.out.println("我是奥迪车,我在进行着色");10 }11 }

View Code

2. BaoMa.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public class BaoMa implementsCar{2 public voidPrepare(){3 System.out.println("我是宝马车,我在进行生产准备");4 }5 public voidInstall(){6 System.out.println("我是宝马车,我在进行组装");7 }8 public voidColor(){9 System.out.println("我是宝马车,我在进行着色");10 }11 }

View Code

3. Suv.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public class Suv implementsCar{2 public voidPrepare(){3 System.out.println("我是SUV车,我在进行生产准备");4 }5 public voidInstall(){6 System.out.println("我是SUV车,我在进行组装");7 }8 public voidColor(){9 System.out.println("我是SUV车,我在进行着色");10 }11 }

View Code

4. Car.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public interfaceCar {2 public abstract voidPrepare();3 public abstract voidInstall();4 public abstract voidColor();5 }

View Code

5. Manager.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classManager {2 public staticCar CreatCar(String type){3 Car car = null;//Manager与Audi类和BaoMa类还有Suv类耦合,进行了硬编码

4 if(type.equals("audi")){5 car=newAuDi();6 }else if(type.equals("baoma")){7 car=newBaoMa();8 }else if(type.equals("suv")){9 car=newSuv();10 }11 car.Prepare();12 car.Install();13 car.Color();14 returncar;15 }16 }

View Code

6. MainTest.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classMainTest {2 public static voidmain(String[] args){3 Manager.CreatCar("audi");4 Manager.CreatCar("baoma");5 Manager.CreatCar("suv");6 }7 }

View Code

7. 运行结果:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 我是奥迪车,我在进行生产准备2 我是奥迪车,我在进行组装3 我是奥迪车,我在进行着色4 我是宝马车,我在进行生产准备5 我是宝马车,我在进行组装6 我是宝马车,我在进行着色7 我是SUV车,我在进行生产准备8 我是SUV车,我在进行组装9 我是SUV车,我在进行着色

View Code

二、使用静态工厂模式的代码

1. AuDi.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public class AuDi implementsCar {2 public voidPrepare(){3 System.out.println("我是奥迪车,我在进行生产准备");4 }5 public voidInstall(){6 System.out.println("我是奥迪车,我在进行组装");7 }8 public voidColor(){9 System.out.println("我是奥迪车,我在进行着色");10 }11 }

View Code

2. BaoMa.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public class BaoMa implementsCar{2 public voidPrepare(){3 System.out.println("我是宝马车,我在进行生产准备");4 }5 public voidInstall(){6 System.out.println("我是宝马车,我在进行组装");7 }8 public voidColor(){9 System.out.println("我是宝马车,我在进行着色");10 }11 }

View Code

3. Suv.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public class Suv implementsCar{2 public voidPrepare(){3 System.out.println("我是SUV车,我在进行生产准备");4 }5 public voidInstall(){6 System.out.println("我是SUV车,我在进行组装");7 }8 public voidColor(){9 System.out.println("我是SUV车,我在进行着色");10 }11 }

View Code

4. Car.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public interfaceCar {2 public abstract voidPrepare();3 public abstract voidInstall();4 public abstract voidColor();5 }

View Code

5. Manager.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classManager {2 Car car = null;3 public Car CreatCar(String type){//Manager类和具体类解耦合,不需要关心具体的类的实现方法。

4 car=CarFactory.getCarInstance(type);//静态方法,不需要使用创建工厂CarFactory来创建对象,直接使用CarFactory来调用其方法。

5 car.Prepare();6 car.Install();7 car.Color();8 returncar;9 }10 }

View Code

6.CarFactory.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classCarFactory {2 public static Car getCarInstance(String type){//静态方法,这样做的缺点是如果CarFactory被继承,getCar不能被重写。

3 Car carInstance = null;4 if(type.equals("audi")){5 carInstance=newAuDi();6 }else if(type.equals("baoma")){7 carInstance=newBaoMa();8 }else if(type.equals("suv")){9 carInstance=newSuv();10 }11 returncarInstance;12 }13 }

View Code

7.MainTest.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public classMainTest {2 public static voidmain(String[] args){3 Manager manager=newManager();4 manager.CreatCar("audi");5 manager.CreatCar("baoma");6 manager.CreatCar("suv");7 }8 }

View Code

8.运行结果:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 我是奥迪车,我在进行生产准备2 我是奥迪车,我在进行组装3 我是奥迪车,我在进行着色4 我是宝马车,我在进行生产准备5 我是宝马车,我在进行组装6 我是宝马车,我在进行着色7 我是SUV车,我在进行生产准备8 我是SUV车,我在进行组装9 我是SUV车,我在进行着色

View Code

【资料下载】

代码demo下载:http://download.csdn.net/detail/xtbda/7096469

【参考资料】

【后面的话】

好好学习,最近学习稍微显得有点乱,要有步骤,有计划。

——TT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值