资讯专栏INFORMATION COLUMN

设计模式之简单工厂模式

mo0n1andin / 3216人阅读

摘要:类型创建型,但不属于中设计模式。简介通过一个专门的工厂类来创建其他类,这些被创建的类通常有一个共同的父类或接口。相关代码简单工厂模式推荐阅读慕课网设计模式精讲简单工厂模式

0x01.定义与类型

定义:由一个工厂对象决定创建出哪一种产品类的实例。

类型:创建型,但不属于GOF23中设计模式。

简介:通过一个专门的工厂类来创建其他类,这些被创建的类通常有一个共同的父类或接口。

uml类图

代码

//产品接口
public interface IProduct {
    void produce();
}

//产品实现
public class Product implements IProduct{
    @Override
    public void produce() {
        System.out.println("产品逻辑");
    }
}

//产品工厂
public class ProductFactory {
    public static IProduct createProduct(String name) {
        Product product = null;
        if ("product".equals(name)) {
            product = new Product();
        }
        return product;
    }
}

应用或测试

public class Test {
    public static void main(String[] args) {
        IProduct product = ProductFactory.createProduct("product");
        product.produce();
    }
}

输出结果

产品逻辑

通过简单工厂模式,可以看到有三个要素

产品接口:产品接口的主要目的是定义产品的规范,所有的产品实现都必须遵循产品接口定义的规范。产品接口是调用者最为关心的,产品接口定义的优劣直接决定了调用者代码的稳定性。同样,产品接口也可以用抽象类来代替,但要注意最好不要违反里氏替换原则。

产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。

产品工厂:静态方法用来生产产品,与调用者直接交互用来提供产品。一般使用静态方法提供,注意当变更发生时,这个类违反了开闭原则。

0x02.适用场景

工厂类负责创建的对象比较少

客户端(应用层)只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心

0x03.简单工厂的优缺点

优点:只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节

缺点:工厂类的职责相对过重,增加新的产品,需要修改工厂类的判断逻辑,违背开闭原则

0x04.简单工厂的实线样例

假设IT教育课程,具有Java, Python等视频。他们都是视频类的子类,而有多带带的视频工厂生产这些课程!

课程基类

public abstract class Video {
    public abstract void produce();
}

视频工厂

public class VideoFactory {
    /**
     * 每次新增加产品实线会修改代码
     * 不符合开闭原则
     * @param type
     * @return
     */
    public Video getVideo(String type) {
        if ("java".equalsIgnoreCase(type)) {
            return new JavaVideo();
        } else if ("python".equalsIgnoreCase(type)) {
            return new PythonVideo();
        } else return null;
    }

    /**
     * 反射方式实现
     * @param clazz
     * @return
     */
    public Video getVideo(Class clazz) {
        Video video = null;
        try {
            video = (Video) Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return video;
    }
}

Java, Python视频的具体实线类

public class JavaVideo extends Video {
    @Override
    public void produce() {
        System.out.println("录制Java课程视频");
    }
}
public class PythonVideo extends Video{
    @Override
    public void produce() {
        System.out.println("录制Python课程");
    }
}

最后的测试类,测试视频工厂输出的视频

public class Test {

//    public static void main(String[] args) {
//        Video video = new JavaVideo();
//        video.produce();
//    }

    public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video1 = videoFactory.getVideo("python");
        if (video1 != null) {
            video1.produce();
        }
        Video video2 = videoFactory.getVideo("java");
        if (video2 != null) {
            video2.produce();
        }
    }

   /* public static void main(String[] args) {
        VideoFactory videoFactory = new VideoFactory();
        Video video = videoFactory.getVideo(PythonVideo.class);
        if (video != null) {
            video.produce();
        }
    }*/
}

输出结果

录制Python课程
录制Java课程视频
0x05.UML类图

如图uml所示:直接的应用类中并没有于具体实现类的耦合,这样当新增具体实现类时是不需要修改应用层业务逻辑

0x06.源码中的简单工厂

Calendar.createCalendar():JDK时间处理类

//根据输入参数区分的具体实现
if (aLocale.hasExtensions()) {
    String caltype = aLocale.getUnicodeLocaleType("ca");
    if (caltype != null) {
        switch (caltype) {
        case "buddhist":
        cal = new BuddhistCalendar(zone, aLocale);
            break;
        case "japanese":
            cal = new JapaneseImperialCalendar(zone, aLocale);
            break;
        case "gregory":
            cal = new GregorianCalendar(zone, aLocale);
            break;
        }
    }
}

jdbc的Class.forname("com.mysql.driver"):通过每个db推出的不同的驱动,通过反射创建出连接。

0x07.相关代码

简单工厂模式:https://github.com/sigmako/design-pattern/tree/master/simple-factory

0x08.推荐阅读

慕课网设计模式精讲: https://coding.imooc.com/class/270.html

简单工厂模式:https://blog.csdn.net/weiwenlongll/article/details/6918164

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74721.html

相关文章

  • PHP面试常考设计模式——工厂模式

    摘要:工厂模式其实可以划分为简单工厂模式工厂方法模式抽象工厂模式等。简单工厂模式介绍简单工厂模式又称为静态工厂方法模式,它属于类创建型模式。此模式是对工厂方法模式的进一步扩展。 你好,是我琉忆,PHP程序员面试笔试系列图书的作者。 本周(2019.3.11至3.15)的一三五更新的文章如下: 周一:PHP面试常考之设计模式——工厂模式周三:PHP面试常考之设计模式——建造者模式周五:PHP...

    Jiavan 评论0 收藏0
  • 优才公开课笔记:php设计模式 (二)工厂模式

    摘要:但本质是,简单工厂并未严格遵循设计模式的开闭原则,当需要增加新产品时也需要修改工厂代码。但是工厂方法则严格遵守开闭原则,模式只负责抽象工厂接口,具体工厂交给客户去扩展。 最近开展了三次设计模式的公开课,现在来总结一下设计模式在PHP中的应用,这是第二篇创建型模式之工厂模式。 设计模式的一般介绍在第一篇文章讲了,这里就不重复。 工厂模式 实现:定义一个用于创建对象的接口,让子类决定实...

    aisuhua 评论0 收藏0
  • Java设计模式(二)——工厂模式

    摘要:需要说明的是在设计模式一书中将工厂模式分为两类工厂方法模式与抽象工厂模式,将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。工厂模式的作用工厂模式的作用封装变化创建逻辑有可能变化,封装成工厂类之后,创建逻辑的变更对调用者透明。1、什么是工厂模式Define an interface for creating an object,but let subclasses decide whi...

    Doyle 评论0 收藏0
  • 一天一个设计模式JS实现——工厂模式

    摘要:参考文章深入理解三种工厂模式工厂模式,工厂方法模式,抽象工厂模式详解工厂模式是中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 参考文章:深入理解java三种工厂模式工厂模式,工厂方法模式,抽象工厂模式 详解 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的...

    Muninn 评论0 收藏0
  • 工厂模式(一)抽象工厂模式

    摘要:主要详解简单工厂模式到抽象工厂模式的演变。抽象工厂模式当一个类别的产品还有多个系列区分时,为了按系列生产商品,使用抽象工厂区分。 主要详解简单工厂模式到抽象工厂模式的演变。 简单工厂模式 即静态工厂模式1.将对象的创建和使用分开;2.将生产过程集中,便于集中管理;3.当需要创建的对象类有变动时,就不用在所有new 的地方修改了,直接修改工厂类即可; /** * 简单工厂模式 ---...

    woshicixide 评论0 收藏0
  • 设计模式系列工厂模式

    摘要:设计模式之工厂模式工厂模式包括了简单工厂工厂方法和抽象工厂。工厂方法模式下面我们针对普通工厂模式的缺点进行优化。 设计模式之工厂模式 工厂模式包括了简单工厂、工厂方法和抽象工厂。下面我从java实际应用的角度分别介绍这三种模式。 简单工厂模式 下面看下JDBC中获取Connection的代码 public class ConnectionFactory { public Con...

    MrZONT 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<