Java设计模式之工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)
工厂模式出现的原因
在java中,创建一个对象最简单的方法就是使用new关键字。但在一些复杂的业务逻辑中,创建一个对象不只需要new一行代码就成了,可能需要一些列的初始化设置,或先创建一些辅助对象来创建这个对象。
在这种场景中,如果需要多次创建这种对象,那每次都要写很多代码。工厂模式的产生就是为了解决这种问题。
工厂模式厉害之处就在于:你不需要知道创建对象的细节就可以轻松的创建你想要的对象,并且产品和工厂是解耦的。
3种工厂模式介绍
1、简单工厂模式
1个具体工厂类,1个抽象产品类,多个具体产品类
每个工厂可以创建多个产品实例,当需要创建新产品的时候,需要修改工厂类,不符合java开闭原则
用户需要什么类型的产品,告诉工厂类,工厂类就创建什么类型的产品实例
2、工厂方法模式
1个抽象工厂类,多个具体工厂类,1个抽象产品类,多个具体产品类
每个工厂只能创建1个产品实例,当需要创建新产品的时候,需要扩展抽象工厂类,而不需要修改,符合java开闭原则
用户需要什么类型的产品,就从什么类型的工厂生产
3、抽象工厂模式
1个抽象工厂类,多个具体工厂类,多个抽象产品类,多个抽象产品类
每个工厂可以创建多个产品实例,当需要创建新产品的时候,需要扩展抽象工厂类,而不需要修改,符合java开闭原则
用户需要什么类型的产品,就从什么类型的工厂生产
用于生产一组相关或者相互依赖的产品
下面以工厂生产宝马车为例子开始具体介绍这3种工厂模式
一、简单工厂模式
需求:用户需要宝马车,并希望工厂根据自己提出的类型可以生产不同类型的宝马车
public abstract class bmw {} public class bmw320 extends bmw {} public class bmw520 extends bmw {} public class bmwfactory { bmw createbmw(integer type){ if(type == 320){ return new bmw320(); }else if(type == 520){ return new bmw520(); }else{ return null; } } } public class customer { public static void main(string[] args) { bmwfactory bmwfactory = new bmwfactory(); bmw mybmw320 = bmwfactory.createbmw(320); //告诉工厂自己需要什么类型的产品 bmw mybmw520 = bmwfactory.createbmw(520); } }
特点:产品和工厂完全耦合,当需要生产新产品的时候,必须修改工厂类的create()方法,违背了java对扩展开放,对修改关闭的原则
二、工厂方法模式
需求:我不希望只有一个工厂来生产所有的宝马车,我希望每种宝马车都由其对应的工厂来生产
public abstract class bmw {} public class bmw320 extends bmw {} public class bmw520 extends bmw {} public abstract class bmwfactory { abstract bmw createbmw(); } public class bmw320factory extends bmwfactory { @override bmw createbmw() { return new bmw320(); } } public class bmw520factory extends bmwfactory { @override bmw createbmw() { return new bmw520(); } } public class customer { public static void main(string[] args) { bmwfactory bmw320factory = new bmw320factory(); bmwfactory bmw520factory = new bmw520factory(); bmw bmw320 = bmw320factory.createbmw(); //需要什么类型的产品,就从什么类型的工厂来生成 bmw bmw520 = bmw520factory.createbmw(); } }
类结构图
特点:产品和工厂完全解耦,当需要生产新产品的时候,只需要扩展新工厂。弊端也很明显,由于每种工厂只生产1中产品,随着新产品越来越多,新工厂也会越来越多
三、抽象工厂模式
需求:用户希望在不同类型的宝马车上可以有不同类型的引擎或空调,如宝马320中安装引擎a和空调a,宝马520中安装引擎b和空调b
引擎类
public abstract class engine { abstract public string show(); } public class enginea extends engine { @override public string show() { return "enginea"; } } public class engineb extends engine { @override public string show() { return "engineb"; } }
空调类
public abstract class aircondition { abstract public string show(); } public class airconditiona extends aircondition { @override public string show() { return "airconditiona"; } } public class airconditionb extends aircondition { @override public string show() { return "airconditionb"; } }
宝马车类
public abstract class bmw { private engine engine; private aircondition aircondition; public engine getengine() { return engine; } public void setengine(engine engine) { this.engine = engine; } public aircondition getaircondition() { return aircondition; } public void setaircondition(aircondition aircondition) { this.aircondition = aircondition; } public abstract string show(); } public class bmw320 extends bmw { @override public string show() { return "我是bmw320,我的引擎:" + getengine().show() + ",我的空调:" + getaircondition().show(); } } public class bmw520 extends bmw { @override public string show() { return "我是bmw520,我的引擎:" + getengine().show() + ",我的空调:" + getaircondition().show(); } }
工厂类
public abstract class bmwfactory { abstract bmw createbmw(); abstract engine createengine(); abstract aircondition createaircondition(); } public class bmw320factory extends bmwfactory { @override bmw createbmw() { bmw bmw320 = new bmw320(); engine enginea = createengine(); aircondition airconditiona = createaircondition(); bmw320.setengine(enginea); bmw320.setaircondition(airconditiona); return bmw320; } @override engine createengine() { return new enginea(); } @override aircondition createaircondition() { return new airconditiona(); } } public class bmw520factory extends bmwfactory { @override bmw createbmw() { bmw bmw520 = new bmw520(); engine engineb = createengine(); aircondition airconditionb = createaircondition(); bmw520.setengine(engineb); bmw520.setaircondition(airconditionb); return bmw520; } @override engine createengine() { return new engineb(); } @override aircondition createaircondition() { return new airconditionb(); } }
用户类
public class customer { public static void main(string[] args) { bmwfactory bmw320factory = new bmw320factory(); bmw bmw320 = bmw320factory.createbmw(); system.out.println(bmw320.show()); bmwfactory bmw520factory = new bmw520factory(); bmw bmw520 = bmw520factory.createbmw(); system.out.println(bmw520.show()); } }
类结构图
运行结果
我是bmw320,我的引擎:enginea,我的空调:airconditiona 我是bmw520,我的引擎:engineb,我的空调:airconditionb
工厂方法模式和抽象工厂模式比较
工厂方法模式中,只有一个抽象产品类,每个工厂只能生产对应类型的产品实例
抽象工厂模式中,有多个抽象产品类,每个工厂可以生产多种类型的产品实例
总结
无论是哪种工厂模式,它们在形式和特点上都是相似的,他们的特点都是为了使产品和工厂解耦。在使用时不必在意具体是工厂方法模式还是抽象工厂模式,因为有时你会发现,明明使用的是工厂方法模式,当新需求来临,对代码稍加扩展或修改,加入一个新产品或方法后,由于产品构成了不同等级的产品族,就变成抽象工厂模式了。而在抽象工厂模式中,当减少一个产品或方法使得工厂提供的产品不再构成产品族后,它就演变成了工厂方法模式。
所以在使用工厂模式时,只需要关心是否降低了耦合度就ok了。
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:
上一篇: Apache Shiro
下一篇: ASP讲座之二:读取通过表单发送的数据