IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式之---工厂模式 -> 正文阅读

[Java知识库]设计模式之---工厂模式

前言

工厂模式,是Java最常用的设计模式之一。属于创建型模式,提供创建对象的最佳方式。适用于创建复杂对象场景。如果是简单对象,比如new就可以的,如果使用工厂模式,就需要引入工厂类,反而增加了复杂度。

复杂对象:类的构造方法参数过多或构造过于复杂,在业务代码中直接引用耦合度较高。后续业务的更改带来的影响和依赖过大,修改地方过多,而工厂模式能很好的解决这些问题。

按照实际业务场景进行划分,工厂模式有3中不同的实现方式:简单工厂模式、工厂方法模式、抽象工厂模式。

简单工厂模式

又叫静态工厂方法模式,有一个具体的工厂类,只需要传入工厂类参数,不需要关心创建对象的逻辑,就可以很方便的创建所需产品。

例如:

public class Client {

    public static void main(String[] args) {
        new SimpleFactory().createProduct("B").print();
    }

    // 抽象产品
    public interface Product {
        void print();
    }

    // 具体产品A
    public static class ProductA implements Product {
        @Override
        public void print() {
            System.out.println("商品A");
        }
    }

    // 具体产品B
    public static class ProductB implements Product {
        @Override
        public void print() {
            System.out.println("商品B");
        }
    }

    // 简单工厂
    public static class SimpleFactory {
        /**
         * 根据入参类型生成具体产品
         */
        public static Product createProduct(String type) {
            switch (type) {
                case "A":
                    return new ProductA();
                case "B":
                    return new ProductB();
            }
            return null;
        }
    }
}

?运行结果:

简单工厂模式在JDK中的应用

private static Calendar createCalendar(TimeZone zone,Locale aLocale)
    {
        CalendarProvider provider =
            LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                                 .getCalendarProvider();
        if (provider != null) {
            try {
                return provider.getInstance(zone, aLocale);
            } catch (IllegalArgumentException iae) {
                // fall back to the default instantiation
            }
        }

        Calendar cal = null;

        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;
                }
            }
        }
        if (cal == null) {
            if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                cal = new BuddhistCalendar(zone, aLocale);
            } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                       && aLocale.getCountry() == "JP") {
                cal = new JapaneseImperialCalendar(zone, aLocale);
            } else {
                cal = new GregorianCalendar(zone, aLocale);
            }
        }
        return cal;
    }

优点:简单方便

缺点:工厂类单一,负责所有产品创建,产品种类增多后,switch ...case分支过多,工厂类将非常臃肿

工厂方法模式

又叫多态性工厂模式,主要解决产品扩展问题。不再是单一的工厂类生产产品,而是由工厂类的子类实现具体产品的创建,因此,当增加一个产品时,只需增加一个相应的工厂子类,避免了工厂类switch ...case分支过多导致的臃肿,符合开闭原则。

例如:

public class Client {

    public static void main(String[] args) {
        new FactoryA().createProduct().print();
        new FactoryB().createProduct().print();
    }

    // 抽象产品
    public interface Product {
        void print();
    }

    // 具体产品A
    public static class ProductA implements Product {
        @Override
        public void print() {
            System.out.println("商品A");
        }
    }

    // 具体产品B
    public static class ProductB implements Product {
        @Override
        public void print() {
            System.out.println("商品B");
        }
    }

    // 抽象工厂
    public interface Factory {
        Product createProduct();
    }

    // 生产ProductA的具体工厂
    public static class FactoryA implements Factory {

        @Override
        public Product createProduct() {
            return new ProductA();
        }
    }

    // 生产ProductB的具体工厂
    public static class FactoryB implements Factory {

        @Override
        public Product createProduct() {
            return new ProductB();
        }
    }
}

?运行结果:?

优点:灵活性增强,解耦。

缺点:具体工厂类的数量容易过多;抽象产品只能生产一种产品,此弊端可由抽象工厂模式解决。

抽象工厂模式

抽象工厂模式是工厂方法模式的扩展,在实际使用中,产品总是按照类型统一出现,而工厂方法模式中,一个子类工厂只能创建一种产品的方式比较鸡肋,我们往往需要一个工厂可以创建出一个类型的多种产品,同时也能降低子工厂类数量的增长速度。

例如:

public class Client {

    public static void main(String[] args) {
        new FactoryA().createProductA().printA();
        new FactoryA().createProductB().printB();
    }

    // 抽象产品A
    public interface ProductA {
        void printA();
    }

    // 抽象产品B
    public interface ProductB {
        void printB();
    }

    // 产品族A的具体产品A
    public static class ProductATypeA implements ProductA {
        @Override
        public void printA() {
            System.out.println("苹果生态的ipad");
        }
    }

    // 产品族A的具体产品B
    public static class ProductBTypeA implements ProductB {
        @Override
        public void printB() {
            System.out.println("苹果产品的macbook");
        }
    }

    // 产品族B的具体产品A
    public static class ProductATypeB implements ProductA {
        @Override
        public void printA() {
            System.out.println("华为生态的matepad");
        }
    }

    // 产品族B的具体产品B
    public static class ProductBTypeB implements ProductB {
        @Override
        public void printB() {
            System.out.println("华为生态的matebook");
        }
    }

    // 抽象工厂
    public interface Factory {
        ProductA createProductA();
        ProductB createProductB();
    }

    // 具体工厂A
    public static class FactoryA implements Factory {

        @Override
        public ProductA createProductA() {
            return new ProductATypeA();
        }

        @Override
        public ProductB createProductB() {
            return new ProductBTypeA();
        }
    }

    // 具体工厂B
    public static class FactoryB implements Factory {

        @Override
        public ProductA createProductA() {
            return new ProductATypeB();
        }

        @Override
        public ProductB createProductB() {
            return new ProductBTypeB();
        }
    }
}

运行结果:

抽象工厂模式在Spring源码中的应用

Spring中,所有的工厂都是BeanFactory的子类,可以通过不同的策略调用getBean方法,获得不同的实例对象。

public interface BeanFactory {

    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
}

优点:需要创建同一类型产品时,即产品族,无需单独创建额外的工厂

缺点:增加了理解难度和抽象性

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 11:46:23  更:2021-09-03 11:46:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:54:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码