一、简介
工厂模式(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、稍微改进
- 经过上面的例子,我们可以通过 CarFactory 对象来创建一个 Car 对象,但是我们发现,这个
produceCar()
方法完全可以变成一个静态方法,这样就可以不用创建 CarFactory 对象,而是直接调用该方法。 - 我们仍然可以单独访问 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()
}
三、相关源码
- 在 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
查看评论