小言_互联网的博客

设计模式篇(三)——工厂模式

466人阅读  评论(0)

一、简介

工厂模式(Factory Pattern) 同属于创建型模式,该模式顾名思义,就是像工厂一样生产一个或多个对象。

定义:在 工厂模式 中,我们创建对象时不对外公开创建逻辑,而是通过 工厂类 来创建的对象。这样就达到了创建对象和使用对象的分离。

实现要素:通过 工厂类 生成对象。

工厂模式建造者模式 比较类似,同样都是将对象的构造和表示分离,不同的是,前者注重于生成对象的结果,后者则是注重于生成对象的过程。

二、实现

工厂模式 的实现非常简单。通常我们说到工厂我们会想到手机厂、汽车厂,那么本篇文章就以汽车工厂为例,来对 工厂模式 进行剖析。

1、最简单的实现

class Car(val brand:String,val modelNum:String)

class CarFactory{

    fun produceCar(name:String,modelNum: String): Car {
        return Car(name,modelNum)
    }
}

fun main() {
    val car = CarFactory().produceCar("领克","05")
}

2、稍微改进

  1. 经过上面的例子,我们可以通过 CarFactory 对象来创建一个 Car 对象,但是我们发现,这个produceCar() 方法完全可以变成一个静态方法,这样就可以不用创建 CarFactory 对象,而是直接调用该方法。
  2. 我们仍然可以单独访问 Car 这个对象,可以跨过 CarFactory 直接new 一个 Car ,所以我们必须采取一些操作。

第一个改进点价格关键词就完事了,第二个改进点有两种方式:

①. 改变 Car的访问限制

Java中,无任何修饰符的类只能在包内调用

/**
 * package com.xxx.package;
 */

class CarJava {

}


public class CarFactoryJava {

    public static CarJava buildCar(){
        return new CarJava();
    }
}

/**
 * package com.xxx.main;
 */
fun main() {
    val car = CarJava()	//爆红,找不到 CarJava 这个类。
}

Kotlin 中,加上 internal 关键字的类,只能在同模块访问。

internal class Car(val brand:String,val modelNum:String)

class CarFactory{

    companion object{

        @JvmStatic
        internal fun produceCar(name:String, modelNum: String): Car {
            return Car(name,modelNum)
        }
    }
}

/**
 * 别的模块中
 */
 fun main() {
    val car = Car()	//爆红,Car 类被 internal 修饰,无法访问。
}

②. 使用内部类

//注 意 私 有 化 构 造 方 法!!!
class Car private constructor(val brand:String,val modelNum:String){

    class CarFactory{

        companion object{
            
            @JvmStatic
            fun produceCar(name:String,modelNum: String): Car {
                return Car(name,modelNum)
            }
        }
    }
}

fun main() {
    val car = Car.CarFactory.produceCar("领克","05")
}

3、返回不同对象

对于 Car 这个类来说实在是太抽象了,我们可以将它作为抽象类,然后创建多个实现类:

abstract class Car(val name:String,val modelNum:String){

    abstract fun getProductPlace():String

    class CarFactory{

        companion object{

            @JvmStatic
            fun<C:Car> produceCar(clazz: Class<C>): Car? {
                when(clazz){
                    Lynk::class.java->{
                        return Lynk("05")
                    }
                    VW::class.java->{
                        return Lynk("迈腾")
                    }
                    BMW::class.java->{
                        return Lynk("750i")
                    }
                }
                return null
            }
        }
    }
}

class Lynk(modelNum: String) : Car("领克", modelNum){

    override fun getProductPlace(): String  = "中国"
}

class VW(modelNum: String) : Car("打死奥拓", modelNum){

    override fun getProductPlace(): String  = "德国"
}

class BMW(modelNum: String) : Car("宝骏", modelNum){

    override fun getProductPlace(): String  = "德国"
}


fun main() {
    val lynk = Car.CarFactory.produceCar(Lynk::class.java)
    val bmw= Car.CarFactory.produceCar(BMW::class.java)
    lynk?.getProductPlace()
}

三、相关源码

  1. MVVM 模式中需要创建一个 ViewModel 对象,我们通常会调用ViewModelProviders.of(this).get(MainViewModel::class.java) 来创建一个 ViewModel 对象,但是我要展示的例子不是这行代码……

    而是这行代码:ViewModelProvider.NewInstanceFactory().create(XXXViewModel::class.java)
class ViewModelProvider{

	... ...
	
	public static class NewInstanceFactory implements Factory {

        private static NewInstanceFactory sInstance;

        static NewInstanceFactory getInstance() {
            if (sInstance == null) {
                sInstance = new NewInstanceFactory();
            }
            return sInstance;
        }

        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            try {
                return modelClass.newInstance();
            } catch (Exception e) {
                ....
            }
        }
    }
}

代码太简单了,自己看吧。

四、小结

工厂模式 实现简单,应用广泛,实乃居家必备之良药✌。


转载:https://blog.csdn.net/catzifeng/article/details/105015273
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场