• 工厂模式


    定义

    1. 简单工厂:由一个工厂对象决定创建出产品的实例。
    2. 工厂方法:定义一个用于创建对象的接口,让使用者决定实例化哪一个类。工厂方法使一个类的实例化延迟到其使用者。
    3. 抽象工厂:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体实现类。

    使用场景

    1. 简单工厂模式将对象的创建和对象的使用进行了分离,屏蔽了中间具体的产品类,让对象的使用者不需要知道对象的创建细节。比如线程池的创建,我们不需要知道ThreadPoolExecutor创建所需的参数,我们只需要直接使用ExecutorService接口就可以。
    public class Executors {
        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>());
        }
    
        public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                          60L, TimeUnit.SECONDS,
                                          new SynchronousQueue<Runnable>());
        }
        ...
    }
    
    1. 工厂方法也是将将对象的创建和对象的使用进行了分离,但是在使用的时候通常是将工厂接口作为参数传入。如ThreadPoolExecutor中的ThreadFactory参数,该参数可以定制线程池中线程的名字,优先级等属性。
    public class ThreadPoolExecutor extends AbstractExecutorService {
        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
    
        }
        ...
    }
    

    实现方式

    工厂方法实现的代码

    package com.fzsyw.test;
    
    /**
     * 产品抽象类
     */
    public abstract class Product {
        public abstract void method(); 
    }
    
    /**
     * 具体A产品
     */
    public class ConcreteProductA extends Product {
        @Override
        public void method() {
            System.out.println("产品A");
        }
    }
    
    /**
     * 具体B产品
     */
    public class ConcreteProductB extends Product {
        @Override
        public void method() {
            System.out.println("产品B");
        }
    }
    
    /**
     * 工厂抽象类
     */
    public abstract class Factory {
        public abstract Product createProduct();
    }
    
    /**
     * 具体工厂
     */
    public class ConcreteFactory extends Factory {
        @Override
        public Product createProduct() {
            return new ConcreteProductA();
        }
    }
    
    /**
     * 客户端使用
     */
    public class Client {
        public static void main(String[] args) {
            Factory factory = new ConcreteFactory();
            Product product = factory.createProduct();
            product.method();
        }
    }
    
    
    public abstract class Factory {
        public abstract <T extends Product> T createProduct(String name);
    }
    
    /**
     * 通过反射的方式
     */
    public class ConcreteFactory extends Factory {
        @Override
        public <T extends Product> T createProduct(String name) {
            Product  product = null;
            try {
                product= (Product) Class.forName(name).newInstance();
                
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return (T) product;
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            Factory factory = new ConcreteFactory();
            Product product = factory.createProduct("com.fzsyw.test.ConcreteProductB");
            product.method();
        }
    }
    
    /**
     * 实际中可能用ApplicationContext或者BeanFactory来获取
     */
    public class ConcreteFactory extends Factory {
        @Autowired
        private ApplicationContext applicationContext;
        
        @Override
        public <T extends Product> T createProduct(String name) {
            return applicationContext.getBean(name, T.class);
        }
    }
    

    扩展与思考

    1. 工厂方法可以说是对简单工厂的升级。简单工厂适用于只有固定的几个产品,不利于扩展,它只能通过在简单工厂中添加新的方法来生产新的产品,不符合开闭原则。工厂方法则是添加了一个工厂的接口,也就是每多一个产品,就要新增一个工厂来进行维护,虽然增加扩展性,但是也带来了复杂性。
    2. 工厂模式有很多变种,如Spring的BeanFactory本身就是产生Bean的工厂,但是它结合了单例模式,默认情况产生的Bean都是单例的。
    3. JDKNumberFormat也用到了简单的工厂模式,但是做了改动,它即是工厂,也是产品(提供了产品的公共方法和抽象方法,抽象方法就由子类实现)。这种模式下,抽象工厂类可以提供通用的代码和统一的访问接口,而具体的子类可以将类的public去掉,让抽象工厂类成为唯一的对外接口。
    public abstract class NumberFormat extends Format  {
    
        public final static NumberFormat getInstance() {
            return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
        }
    
        public static NumberFormat getInstance(Locale inLocale) {
            return getInstance(inLocale, NUMBERSTYLE);
        }
    
        /**
            * 通用的接口,不用子类实现
            */
        public final String format(long number) {
            return format(number, new StringBuffer(),
                          DontCareFieldPosition.INSTANCE).toString();
        }
    
        /**
            * 特定接口,由子类实现
            */
        public abstract StringBuffer format(double number,
                                            StringBuffer toAppendTo,
                                            FieldPosition pos);
        ...
    }
    
  • 相关阅读:
    [置顶] 大型网站技术架构(六)网站的伸缩性架构
    [置顶] 大型网站技术架构(五)网站高可用架构
    [置顶] 大型网站技术架构(五)网站高可用架构
    [置顶] 大型网站技术架构(四)网站的高性能架构
    [置顶] 大型网站技术架构(四)网站的高性能架构
    [置顶] 大型网站技术架构(三)架构核心要素
    [置顶] 大型网站技术架构(二)架构模式
    [置顶] 大型网站技术架构(二)架构模式
    [置顶] 大型网站技术架构(一)大型网站架构演化
    [置顶] 大型网站技术架构(一)大型网站架构演化
  • 原文地址:https://www.cnblogs.com/fzsyw/p/11281600.html
Copyright © 2020-2023  润新知