美文网首页
一起来学习设计模式:工厂模式

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

作者: __y | 来源:发表于2018-06-01 11:16 被阅读10次

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

    效果:


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

    效果:


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

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


    image.png

    基本架构图


    image.png

    抽象工厂和工厂方法比较

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

    3.总结

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

    相关文章

      网友评论

          本文标题:一起来学习设计模式:工厂模式

          本文链接:https://www.haomeiwen.com/subject/tcxfsftx.html