设计模式之---工厂模式

本文详细介绍了工厂模式在Java中的三种实现:简单工厂模式、工厂方法模式和抽象工厂模式,并通过实例展示了它们的使用。简单工厂模式适合创建简单对象,但随着产品增多,代码会变得臃肿。工厂方法模式解决了扩展问题,但可能产生过多工厂类。抽象工厂模式则用于创建一系列相关或相互依赖的对象,降低了子工厂类的数量。此外,还分析了这些模式在JDK和Spring框架中的应用及其优缺点。
摘要由CSDN通过智能技术生成

前言

工厂模式,是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;
}

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

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值