一起来学习设计模式:工厂模式

前言:
这次我们来看看工厂模式,工厂模式和抽象工厂模式是在日常开发中使用非常广泛的设计模式。我们所熟知的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();
    }
}

一起来学习设计模式:工厂模式_第1张图片
image.png

如果我们这时候要想体验三星手机了,就创建一个三星手机类和工厂,分别实现和继承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();
    }
}

一起来学习设计模式:工厂模式_第2张图片
image.png

这时候我们想想,这些都是属于苹果的产品,用一个专门生产苹果产品的工厂来管理岂不是那好(也方便我们以后的代码维护)?
下面创建一个苹果系列产品工厂

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();
    }
}

效果:


一起来学习设计模式:工厂模式_第3张图片
image.png

可是现在问题来了,最近苹果用腻了,想换一种口味,听说小米的系列产品口碑不错,想换一个系列。这个时候我们参考苹果工厂,创建一个小米工厂,专门生产小米系列的产品

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();
    }
}

效果:


一起来学习设计模式:工厂模式_第4张图片
image.png

效果看上去没问题,可是问题来了,如果我以后又想换微软系列产品,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();
    }
}

一起来学习设计模式:工厂模式_第5张图片
image.png

再试试苹果的
我们只要改一行代码
Factory factory = new AppleFactory();


一起来学习设计模式:工厂模式_第6张图片
image.png

基本架构图


一起来学习设计模式:工厂模式_第7张图片
image.png

抽象工厂和工厂方法比较

1.抽象工厂缺点很明显,增加新的产品比较难操作,要动几个抽象类;
2.抽象工厂更适合用生产系列产品;
3.工厂方法适合增加新的产品品种;

3.总结

总的来说我们使用简单工厂模式比较多,工厂方法模式的话代码量比较多,抽象工厂模式需要业务大的才会用(比如说奇迹暖暖等换装,换皮肤游戏等)。
参考资料:
https://www.imooc.com/article/30206 -- 工厂模式理解了没有

你可能感兴趣的:(一起来学习设计模式:工厂模式)