我们来学习工厂模式,有的小伙伴可能会说起航篇里的大纲中没有这个模式呀,这是从哪冒出来的。事实确实如此,工厂模式包含了简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式也没有在大纲中出现,这个是较早出现的工厂模式。
大白话来说就是,当我们需要一个对象时,不需要知道具体的创建过程,只需要问工厂要即可。由此可见,工厂的作用就是为我们创建对象。
举个栗子,比如你要去买书,可能想买《Java编程思想》,也可能是《Effective Java》又或者是《深入理解Java虚拟机》,这种情况下直接去书店就能满足你的需求。这里的书店就充当工厂的作用。
简单工厂模式也叫静态工厂方法,根据传入的参数不同返回相应的对象。实现该方法所在的类就是简单工厂类。如下图所示:
这里以支付为例,日常生活中大家在付款时,用的比较多的就是支付宝和微信了。根据这个场景我们来实现简单工厂的代码。
第一步:创建支付接口
/**
* 第一步:创建抽象产品接口,定义抽象方法,让具体的产品类去实现具体业务
*/
public interface IPay {
/**
* 定义统一支付方法
*/
void unifiedorder();
}12345678910复制代码类型:[java]
第二步:创建具体的业务实现
/**
* 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
*/
public class AliPay implements IPay {
@Override
public void unifiedorder() {
System.out.println("调用阿里支付");
}
}
/**
* 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
*/
public class WechatPay implements IPay{
@Override
public void unifiedorder() {
System.out.println("调用微信支付");
}
}123456789101112131415161718192021复制代码类型:[java]
第三步:创建简单工厂
/**
* 第三步:创建简单工厂类,负责创建用户所需的对象
*/
public class SimplePayFactory {
/**
* 获取支付对象方法
* @param beanName
* @return
*/
public static IPay getPayInstance(String beanName) {
if (beanName.equalsIgnoreCase("AliPay")) {
return new AliPay();
} else if (beanName.equalsIgnoreCase("WechatPay")) {
return new WechatPay();
} else {
return null;
}
}
}1234567891011121314151617181920复制代码类型:[java]
第四步:测试
public class SimpleFactoryTest {
public static void main(String[] args) {
IPay aliPay = SimplePayFactory.getPayInstance("AliPay");
aliPay.unifiedorder();
IPay wechatPay = SimplePayFactory.getPayInstance("WechatPay");
wechatPay.unifiedorder();
}
}123456789复制代码类型:[java]
运行结果:
调用阿里支付
调用微信支付12复制代码类型:[java]
优点:解耦
缺点:
违背开闭原则,新增Product类需要修改 getPayInstance 代码
一定程度上增加了类的数量
不利于系统的维护和扩展
工厂方法模式又称工厂模式,是简单工厂的一个变种,解决了开闭原则问题。用户只需要知道具体工厂的名称就可以拿到相应的对象。如下图所示:
还是以支付为例,在工厂方法中,原有内容保持不变,但多了一层获取具体工厂的接口。
第一步:创建支付接口
**
* 第一步:创建抽象产品接口,定义抽象方法,让具体的产品类去实现具体业务
*/
public interface IPay {
/**
* 定义统一支付方法
*/
void unifiedorder();
}12345678910复制代码类型:[java]
第二步:创建具体的业务实现
/**
* 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
*/
public class AliPay implements IPay {
@Override
public void unifiedorder() {
System.out.println("调用阿里支付");
}
}
/**
* 第二步:创建具体产品类,实现抽象产品接口,并实现具体的业务方法
*/
public class WechatPay implements IPay{
@Override
public void unifiedorder() {
System.out.println("调用微信支付");
}
}123456789101112131415161718192021复制代码类型:[java]
第三步:创建获取支付对象的工厂
/**
* 第三步:抽象工厂类,用于描述具体工厂的公共接口
*/
public interface IPayFactory {
/**
* 具体工厂的抽象方法
* @return IPay
*/
IPay getPay();
}1234567891011复制代码类型:[java]
第四步:创建具体工厂类
/**
* 第四步:具体工厂类,实现抽象工厂接口,完成对象创建
*/
public class AlipayFactory implements IPayFactory{
@Override
public IPay getPay() {
return new AliPay();
}
}
/**
* 第四步:具体工厂类,实现抽象工厂接口,完成对象创建
*/
public class WechatFactory implements IPayFactory{
@Override
public IPay getPay() {
return new WechatPay();
}
}123456789101112131415161718192021复制代码类型:[java]
第五步:测试
public class MethodFactoryTest {
public static void main(String[] args) {
IPayFactory alipayFactory = new AlipayFactory();
IPay aliPay = alipayFactory.getPay();
aliPay.unifiedorder();
IPayFactory wechatFactory = new WechatFactory();
IPay wechatPay = wechatFactory.getPay();
wechatPay.unifiedorder();
}
}
123456789101112复制代码类型:[java]
运行结果:
调用阿里支付
调用微信支付12复制代码类型:[java]
优点:
解耦
符合开闭原则
提高了扩展性和复用性
缺点:
类数量过多,工厂越多复杂性越高
更具抽象性,增加了理解成本
抽象产品接口只能生产一种产品
通过工厂方法的学习,大家也可以感觉到该模式只考虑同类型的产品,但是生活中同样有很多综合型的工厂,如大学有很多的专业,企业里有很多的岗位等等,这就造就了抽象工厂模式。
为了更好的理解抽象工厂,我们先来了解下产品的相关概念,如下图所示:
简单工厂模式不建议在产品种类多的情况下使用
接下来就以苹果和华为公司生产电脑和手机为例,实现抽象工厂。如下图所示:
第一步:创建产品工厂
/**
* 第一步:创建电脑工厂,并定义功能
*/
public interface IComputerFactory {
/**
* 开机
*/
void start();
/**
* 关机
*/
void stop();
}
/**
* 第一步:创建手机工厂,并定义功能
*/
public interface IPhoneFactory {
/**
* 开机
*/
void start();
/**
* 关机
*/
void stop();
}12345678910111213141516171819202122232425262728293031复制代码类型:[java]
第二步:创建具体产品
创建苹果产品:
/**
* 第二步:创建具体产品(苹果电脑)
*/
public class Mac implements IComputerFactory{
@Override
public void start() {
System.out.println("苹果电脑开机");
}
@Override
public void stop() {
System.out.println("苹果电脑关机");
}
}
/**
* 第二步:创建具体产品(苹果手机)
*/
public class IPhone implements IPhoneFactory{
@Override
public void start() {
System.out.println("苹果手机开机");
}
@Override
public void stop() {
System.out.println("苹果手机关机");
}
}123456789101112131415161718192021222324252627282930复制代码类型:[java]
创建华为产品:
/**
* 第二步:创建具体产品(华为电脑)
*/
public class HuaWeiComputer implements IComputerFactory{
@Override
public void start() {
System.out.println("华为电脑开机");
}
@Override
public void stop() {
System.out.println("华为电脑关机");
}
}
/**
* 第二步:创建具体产品(华为手机)
*/
public class HuaWeiPhone implements IPhoneFactory{
@Override
public void start() {
System.out.println("华为手机开机");
}
@Override
public void stop() {
System.out.println("华为手机关机");
}
}123456789101112131415161718192021222324252627282930复制代码类型:[java]
第三步:创建企业工厂
/**
* 第三步:创建企业工厂(苹果工厂)
*/
public class AppleFactory implements IProductFactory{
@Override
public IPhoneFactory phoneProduct() {
return new IPhone();
}
@Override
public IComputerFactory computerProduct() {
return new Mac();
}
}
/**
* 第三步:创建企业工厂(华为工厂)
*/
public class HuaWeiFactory implements IProductFactory{
@Override
public IPhoneFactory phoneProduct() {
return new HuaWeiPhone();
}
@Override
public IComputerFactory computerProduct() {
return new HuaWeiComputer();
}
}12345678910111213141516171819202122232425262728293031复制代码类型:[java]
第四步:创建最上层抽象工厂
/**
* 第四步:创建最上层抽象工厂
*/
public interface IProductFactory {
/**
* 生产手机
* @return IPhoneFactory
*/
IPhoneFactory phoneProduct();
/**
* 生产电脑
* @return IComputerFactory
*/
IComputerFactory computerProduct();
}1234567891011121314151617复制代码类型:[java]
第五步:抽象工厂测试
public class AbstractFactoryTest {
public static void main(String[] args) {
// 苹果产品系列
IProductFactory appleFactory = new AppleFactory();
IComputerFactory appleComputerFactory = appleFactory.computerProduct();
appleComputerFactory.start();
appleComputerFactory.stop();
IPhoneFactory applePhoneFactory = appleFactory.phoneProduct();
applePhoneFactory.start();
applePhoneFactory.stop();
System.out.println("======================");
// 华为产品系列
IProductFactory huaWeiFactory = new HuaWeiFactory();
IComputerFactory huaWeiComputerFactory = huaWeiFactory.computerProduct();
huaWeiComputerFactory.start();
huaWeiComputerFactory.stop();
IPhoneFactory huaWeiPhoneFactory = huaWeiFactory.phoneProduct();
huaWeiPhoneFactory.start();
huaWeiPhoneFactory.stop();
}
}12345678910111213141516171819202122复制代码类型:[java]
运行结果:
苹果电脑开机
苹果电脑关机
苹果手机开机
苹果手机关机
====分割线====
华为电脑开机
华为电脑关机
华为手机开机
华为手机关机123456789复制代码类型:[java]
优点:工厂方法的扩展,实现了产品族生产。
缺点:
不是很符合开闭原则
产品族扩展困难
比工厂方法更抽象,理解更困难
通过本篇文章的学习,总结以下几点:
简单工厂模式不建议在产品种类多的情况下使用
工厂方法模式适用于多种厂家生产类似产品,项目中使用频率较低
抽象工厂是工厂方法的扩展,实现了产品族生产
抽象工厂在实际开发中的出现的频率更低
抽象工厂中每个工厂只生产一个产品时建议使用工厂方法
是工厂方法的扩展,实现了产品族生产
抽象工厂在实际开发中的出现的频率更低
抽象工厂中每个工厂只生产一个产品时建议使用工厂方法
还款前如何查询我的贷款信息?可选择手机银行“首页—贷款—我的贷款”查询您名下的建行贷款基本信息(如贷款种类、还款账号、利率、贷款金额、月还款额等)。还款日前有短信提醒吗?当您扣款账户余额不足时,建行会在还款日前(各分行提前日期有所差异)向您发送提示短信,提醒您及时将足额资金存入还款账户。(只要您在建
放量下跌与缩量回调是什么意思。放量下跌是指平常每天成交量固定不是很大,突然有一天成交量达到一定多的量,比较前几日成交量要大很多,这就叫放量。放量下跌可能是对于市场前景感到悲观,认为股价还将会继续下跌,因此放大下跌成交量。股票或指数的基本面或消息面出现不利变化。技术面出现破位,技术指标被打破等等,导致