美文网首页
Factory Pattern(工厂模式)

Factory Pattern(工厂模式)

作者: 一个追寻者的故事 | 来源:发表于2020-09-07 20:31 被阅读0次

    工厂模式中的 「工厂」是什么

    「工厂」是生产一些产品的地方

    生产什么?

    生产 「对象」

    工厂模式用来生产对象,使用 new 也可以创建对象。但是工厂模式可以给代码带来更大的扩展性和尽量少的修改量。

    为什么使用工厂模式(使用场景)

    1. 解耦 :把对象的创建和使用过程分开
    2. 封装: 如果创建一个对象的过程很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。
    3. 可扩展、易维护:对象创建过程由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建对象的地方逐个修正,只需在工厂里修改即可,降低维护成本。

    一、简单工厂

    abstract class Car() {
        abstract fun run()
    }
    
    class Audi : Car() {
        override fun run() {
            println("Audi is running")
        }
    }
    
    class Jeep : Car() {
        override fun run() {
            println("Jeep is running")
        }
    }
    
    class Factory {
        companion object {
            val AUDI = "Audi"
            val JEEP = "Jeep"
            fun createCar(brand: String): Car {
                return when (brand) {
                    AUDI -> Audi()
                    JEEP -> Jeep()
                    else -> throw IllegalArgumentException("wrong input")
                }
            }
        }
    }
    
    fun main() {
        Factory.createCar(Factory.AUDI).run()
    }
    

    二、工厂方法

    简单工厂有个小问题,每次有新的类型创建时,都要修改Factory,有点违反开闭原则。工厂方法模式是简单工厂的进一步深化,在工厂方法模式中,不在提供一个统一的工厂来创建所有的对象,而是针对不同的对象创建不同的工厂,也就说每个对象都有一个与之对应的工厂。

    abstract class Car() {
        abstract fun run()
    }
    
    class Audi : Car() {
        override fun run() {
            println("Audi is running")
        }
    }
    
    class Jeep : Car() {
        override fun run() {
            println("Jeep is running")
        }
    }
    
    interface Factory {
        fun createCar(): Car
    }
    
    class AudiFactory : Factory {
        override fun createCar(): Car {
            return Audi()
        }
    }
    
    class JeepFactory : Factory {
        override fun createCar(): Car {
            return Jeep()
        }
    }
    
    fun main() {
        val jeep = JeepFactory().createCar()
        jeep.run()
    }
    

    三、抽象工厂

    在前边的 简单工厂、抽象工厂,潜意识里我们生产的都是同一类产品。抽象工厂是工厂方法的进一步深化,不单单可以创建一种产品,还可以创建一组产品。

    abstract class Tire {
        abstract fun tire()
    }
    
    class AudiTire : Tire() {
        override fun tire() {
            println("This is AudiTire")
        }
    }
    
    class JeepTire: Tire(){
        override fun tire() {
            println("This is JeepTire")
        }
    }
    
    abstract class Engine{
        abstract fun run()
    }
    
    class AudiEngine : Engine(){
        override fun run() {
            println("AudiEngine is running")
        }
    }
    
    class JeepEngine : Engine(){
        override fun run() {
            println("JeepEngine is running")
        }
    }
    
    interface Factory{
        fun createTire(): Tire
        fun createEngine(): Engine
    }
    
    class AudiFactory : Factory{
        override fun createEngine(): Engine {
            return AudiEngine()
        }
    
        override fun createTire(): Tire {
            return AudiTire()
        }
    }
    
    class JeepFactory : Factory{
        override fun createEngine(): Engine {
            return JeepEngine()
        }
    
        override fun createTire(): Tire {
            return JeepTire()
        }
    }
    
    fun main() {
        val engine = AudiFactory().createEngine()
        val tire = AudiFactory().createTire()
    
        engine.run()
        tire.tire()
    
    }
    

    四、展示一个 jdk 中 工厂方法的使用

    public interface ThreadFactory {
    
        /**
         * 创建一个新的Thread实例,返回的内容可能初始化了优先级、线程名称、是否后台线程等相关状态。
         * @param r a runnable to be executed by new thread instance
         * @return constructed thread, or {@code null} if the request to
         *         create a thread is rejected
         */
        Thread newThread(Runnable r);
    }
    

    这就是一个 工厂方法 的一个实践。

    ThreadFactory : 可以按需生产新的Thread。使用ThreadFactory可以避免使用 new Thread(Runnable)这种生硬的写法,而且可以给生成的线程指定各种属性,例如优先级等。 接下来看一个 ThreadFactory的实现:DefaultThreadFactory

        private static class DefaultThreadFactory implements ThreadFactory {
            private static final AtomicInteger poolNumber = new AtomicInteger(1);
            private final ThreadGroup group;
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            private final String namePrefix;
    
            DefaultThreadFactory() {
                SecurityManager s = System.getSecurityManager();
                group = (s != null) ? s.getThreadGroup() :
                                      Thread.currentThread().getThreadGroup();
                namePrefix = "pool-" +
                              poolNumber.getAndIncrement() +
                             "-thread-";
            }
    
            //设置了线程为非后台线程;优先级为NORMAL
            public Thread newThread(Runnable r) {
                Thread t = new Thread(group, r,
                                      namePrefix + threadNumber.getAndIncrement(),
                                      0);
                if (t.isDaemon())
                    t.setDaemon(false);
                if (t.getPriority() != Thread.NORM_PRIORITY)
                    t.setPriority(Thread.NORM_PRIORITY);
                return t;
            }
        }
    

    DefaultThreadFactory 是一个 工厂的具体实现,我们可以看到创建一个特定类型的Thread需要的代码还是有一定的复杂度,这时候使用 工厂方法 很合适。不同的 ThreadFactory子类可以创建特定特色的线程。

    相关文章

      网友评论

          本文标题:Factory Pattern(工厂模式)

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