前言:
这次我们来看看工厂模式,工厂模式和抽象工厂模式是在日常开发中使用非常广泛的设计模式。我们所熟知的sping也有应用工厂模式的设计模式。它主要用于实现将对象的实例化部分取出来,进而优化系统架构,增强系统的扩展性。
这个时候又想加一句。设计模式都是人们想起来的偷懒方式~哈哈哈哈
1.工厂模式概述
实例化对象,用工厂方法代替new的操作。工厂模式包括工厂方法模式和抽象工厂模式。我们可以在生产过程中加工制作,DIY自己的产品。
2.如何使用工厂模式
下面用的代码实例都是非常简单的,我们重要的是体验里面的思想,不要拘泥于表现的形式。工厂模式要大型项目or框架上用是比较频繁的,来感受模式的强大吧!
工厂方法模式的实现
1.笔者我最近买了一台小米手机,用里面连接wifi的功能
public interface Connectable {
void connect();
}
创建一个小米类,实现上面的接口
public class Mi implements Connectable {
@Override
public void connect() {
System.out.println("小米手机连接wifi");
}
}
创建一个苹果类,实现上面的接口
public class Iphone implements Connectable {
@Override
public void connect() {
System.out.println("iphone 连接wifi");
}
}
使用小米的类创建对象
public class Test {
public static void main(String[] args) {
//我现在用的是小米的手机,使用连接wifi的功能
Mi phone = new Mi();
phone.connect();
}
}
OK,现在我们看看,现在我们是new出来的;这个时候如果我们想加点权限控制之类的功能,就是要对小米手机的连接wifi功能使用的时候加工。这时候我们就非常难操作了,我们需要创建一个工厂专门生产小米手机,在出厂前就做好加工工作!
小米工厂
public class MiFactory {
public Connectable createPhone() {
return new Mi();
}
}
利用小米工厂生产产品,使用产品
public class Test {
public static void main(String[] args) {
//我现在用的是小米的手机,使用连接wifi的功能
MiFactory factory = new MiFactory();
Connectable phone = factory.createPhone();
phone.connect();
}
}
好了笔者使用小米手机一段时间后,看到苹果8面世了!没用过苹果的土鳖想试一试苹果手机的感觉(试一试卖肾的感觉~)
这时候创建一个工厂苹果的工厂
public class IphoneFactory {
public Connectable createPhone(){
return new Iphone();
}
}
手机到了,马上试用!
public class Test {
public static void main(String[] args) {
//我现在用的是小米的手机,使用连接wifi的功能
IphoneFactory factory = new IphoneFactory();
Connectable phone = factory.createPhone();
phone.connect();
}
}
OK,体验到了苹果手机的wifi功能了!
不过这时候我们可以观察到我换手机要把工厂改成:
IphoneFactory factory = new IphoneFactory();
那如果我下次想用三星手机了,岂不是又要改这段代码,这真的太麻烦了。怎么解决呢?简单,创建一个父类的工厂就好了!
创建一个抽象类
public abstract class PhoneFactory {
public abstract Connectable createPhone();
}
苹果手机工厂和小米手机工厂分别继承PhoneFactory
public class IphoneFactory extends PhoneFactory{
public Connectable createPhone(){
return new Iphone();
}
}
public class MiFactory extends PhoneFactory{
public Connectable createPhone() {
return new Mi();
}
}
这时候我们客户端(Test类),也得改改
public class Test {
public static void main(String[] args) {
//我现在用的是小米的手机,使用连接wifi的功能
PhoneFactory factory = new IphoneFactory();
Connectable phone = factory.createPhone();
phone.connect();
}
}
如果我们这时候要想体验三星手机了,就创建一个三星手机类和工厂,分别实现和继承Connecable和PhoneFactory
在客户端中改:
PhoneFactory factory = new XXXXFactory();
优点:
1.客户端不再负责对象的创建,明确地分了各个类的职责,很好地完成了解耦;
2.增加了系统的可扩展性
缺点:
1.需要额外的增加代码;
2.只能定制一种产品;
简单/静态工厂模式
public class AllPhoneFactory {
public static Connectable createPhone(String type) {
Connectable instance = null;
if("iphone".equals(type))
instance = new Iphone();
if("Mi".equals(type))
instance = new Mi();
return instance;
}
}
很简单,代码量也相对较少,如果我们想继续增加三星手机的话还要往里面加代码,当需求不断增加就要在原有基础上一直加代码。
抽象工厂模式
抽象工厂的话比较复杂,我们一般的应用用不到(先奶一口!),下面来模拟一下。
最近比较热衷于苹果的产品,喜欢用苹果的平板,喜欢用苹果的手机
public class ApplePhone {
public void call() {
System.out.println("苹果打电话........");
}
}
public class Ipad {
public void play() {
System.out.println("玩苹果平板......");
}
}
public class Test {
public static void main(String[] args) {
ApplePhone phone = new ApplePhone();
Ipad pad = new Ipad();
phone.call();
pad.play();
}
}
这时候我们想想,这些都是属于苹果的产品,用一个专门生产苹果产品的工厂来管理岂不是那好(也方便我们以后的代码维护)?
下面创建一个苹果系列产品工厂
public class AppleFactory {
public ApplePhone createPhone() {
return new ApplePhone();
}
public Ipad createPad() {
return new Ipad();
}
}
改一下Test类
public class Test {
public static void main(String[] args) {
AppleFactory factory = new AppleFactory();
ApplePhone phone = factory.createPhone();
Ipad pad = factory.createPad();
phone.call();
pad.play();
}
}
效果:
可是现在问题来了,最近苹果用腻了,想换一种口味,听说小米的系列产品口碑不错,想换一个系列。这个时候我们参考苹果工厂,创建一个小米工厂,专门生产小米系列的产品
public class MiFactory {
public MiPhone createPhone(){
return new MiPhone();
}
public Mipad createPad(){
return new Mipad();
}
}
Test类修改一下,用小米产品咯~
public class Test {
public static void main(String[] args) {
MiFactory factory = new MiFactory();
MiPhone phone = factory.createPhone();
Mipad pad = factory.createPad();
phone.call();
pad.play();
}
}
效果:
效果看上去没问题,可是问题来了,如果我以后又想换微软系列产品,Test类又要大改,这不利于我们的扩展。接下来让再优化一下!
创建一个抽象类Phone
public abstract class Phone {
public abstract void call();
}
然后分别让MiPhone和ApplePhone继承这个父类
public class MiPhone extends Phone{
public void call() {
System.out.println("小米手机.....");
}
}
public class ApplePhone extends Phone{
public void call() {
System.out.println("苹果打电话........");
}
}
再创建一个Pad抽象类
public abstract class Pad {
public abstract void play();
}
让Ipad和MiPad继承这个抽象类
public class Ipad extends Pad{
public void play() {
System.out.println("玩苹果平板......");
}
}
public class Mipad extends Pad{
public void play() {
System.out.println("玩小米平板");
}
}
接下来创建一个工厂出现类,让小米工厂和苹果工厂继承这个抽象工厂类
public abstract class Factory {
//创建手机
public abstract Phone createPhone();
//创建pad
public abstract Pad createPad();
}
public class AppleFactory extends Factory{
public Phone createPhone() {
return new ApplePhone();
}
public Pad createPad() {
return new Ipad();
}
}
public class MiFactory extends Factory{
public Phone createPhone(){
return new MiPhone();
}
public Pad createPad(){
return new Mipad();
}
}
最后来修改一下Test类的代码
public class Test {
public static void main(String[] args) {
Factory factory = new MiFactory();
Phone phone = factory.createPhone();
Pad pad = factory.createPad();
phone.call();
pad.play();
}
}
再试试苹果的
我们只要改一行代码
Factory factory = new AppleFactory();
基本架构图
抽象工厂和工厂方法比较
1.抽象工厂缺点很明显,增加新的产品比较难操作,要动几个抽象类;
2.抽象工厂更适合用生产系列产品;
3.工厂方法适合增加新的产品品种;
3.总结
总的来说我们使用简单工厂模式比较多,工厂方法模式的话代码量比较多,抽象工厂模式需要业务大的才会用(比如说奇迹暖暖等换装,换皮肤游戏等)。
参考资料:
https://www.imooc.com/article/30206 -- 工厂模式理解了没有