Kotlin基础知识的学习,请参考之前的文章:

Kotlin入门第一课:从对比Java开始

Kotlin入门第二课:集合操作

Kotlin入门第三课:数据类型

初次尝试用Kotlin实现Android项目

学习一门语言,没有必要掌握全部特性才去实践。入门之后可以开始阅读好的开源项目代码,自己动手实现一些简单的案例,有困难再去补充学习相关的知识点,这样反复的过程效果会比较好。

最近在重新学习设计模式,正好用Kotlin来实现对应的示例代码。本文就从简单工厂模式开始。

说明:设计模式的文字性解释参考或引用了这篇文章,作者的设计模式系列文章写得挺不错,感兴趣的朋友可以移步去阅读。由于作者没有给出具体的示例代码,所以本人打算在学习的同时,利用Java和Kotlin将各个模式实现一遍(虽然网上有现成代码),写出总结。目的是学习设计模式和Kotlin语言,分享学习过程。

1. 定义

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

2. 结构

Factory:工厂角色,负责实现创建所有实例的内部逻辑;

Product:抽象产品角色,是所创建的所有对象的父类,负责描述所有实例所共有的公共接口;

ConcreteProduct:具体产品角色,是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

3. 代码

3.1 Java

Product:

 abstract class Product {
     abstract void print();
 }

定义了产品抽象角色,及抽象方法print。

ConcreteProductA与ConcreteProductB:

 class ConcreteProductA extends Product {
     void print() {
         System.out.println("print of ConcreteProductA");
     }
 }

 class ConcreteProductB extends Product {
     void print() {
         System.out.println("print of ConcreteProductB");
     }
 }

定义了两个具体产品角色,分别实现了print方法。

Factory:

 class Factory {
     Product createProduct(String tag) {
         Product product = null;
         switch (tag) {
             case "A":
                 product = new ConcreteProductA();
                 System.out.println("create ProductA");
                 break;
             case "B":
                 product = new ConcreteProductB();
                 System.out.println("create ProductB");
                 break;
             default:
                 break;
         }

         return product;
     }
 }

工厂角色,实现了根据传入的参数来创建产品的功能。注意,新版的Java才能将String类型作为switch参数。

SimpleFactoryPattern:

 public class SimpleFactoryPattern {
     public static void main(String[] args) {
         System.out.println("Simple Factory Pattern");

         Factory factory = new Factory();
         Product product = factory.createProduct("A");
         if (product != null) {
             product.print();
         }
         product = factory.createProduct("B");
         if (product != null) {
             product.print();
         }
         product = factory.createProduct("C");
         if (product != null) {
             product.print();
         }
     }
 }

测试用例,代码中加入了产品对象是否为null的判断,因为当用户传入错误的参数时是不能得到想要的产品的。

输出:

3.2 Kotlin

由于Kotlin和Java的实现只是代码上的不同,所以下面只会说明存在差异的地方。以后要想由Kotlin转向Java,得先从细节上慢慢积累。虽然大多知识点在前面几篇文章有讲到,但还是会提一下,温故而知新。

Product:

 abstract class Product {
     abstract fun print()
 }

方法定义添加fun关键字;语句结尾没有分号。

ConcreteProductA与ConcreteProductB:

 class ConcreteProductA : Product() {
     override fun print() {
         println("print of ConcreteProductA")
     }
 }

 class ConcreteProductB : Product() {
     override fun print() {
         println("print of ConcreteProductB")
     }
 }

类继承用分号代替extends关键字,基类名后添加括号;方法覆写添加override关键字;输出方法类似Python,没有System.out等繁琐的前缀。

Factory:

 class Factory {
     fun createProduct(tag: String): Product? {
         var product: Product? = null
         when (tag) {
             "A" -> {
                 product = ConcreteProductA()
                 println("create ProductA")
             }
             "B" -> {
                 product = ConcreteProductB()
                 println("create ProductB")
             }
             else -> {
             }
         }

         return product
     }
 }

方法参数是变量在前,类型在后,用冒号隔离;方法返回类型写在方法名定义后,用冒号分离;没有返回值则可不写类型,或者写Unit;不确定对象是否为空,声明时须加上问号;用when代替switch更简洁易用。

SimpleFactoryPattern:

 fun main(args: Array<String>) {
     println("Simple Factory Pattern")

     val factory = Factory()
     var product: Product? = factory.createProduct("A")
     if (product != null) {
         product.print()
     }
     product = factory.createProduct("B")
     if (product != null) {
         product.print()
     }
     product = factory.createProduct("C")
     if (product != null) {
         product.print()
     }
 }

主方法不需要在外面套一个public类;对象创建不用加new关键字。

输出同上。

4. 优缺点

4.1 优点

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象;

客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量;

通过引入配置文件,可以在不修改任何客户端代码的情况下更换或增加新的具体产品类,在一定程度上提高了系统的灵活性。

4.2 缺点

由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响;

使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度;

系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护;

简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

5. 适用场景

工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂;

客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。

Kotlin入门第四课:简单工厂模式的更多相关文章

  1. Linux零基础入门第四课

    根据直播讲义整理的内容,从第四课开始.前三课的内容若后面有精力会一并整理进来. 文件的基本操作(上) 创建.删除.复制.移动和重命名 touch命令创建文件 语法 >$ touch file0 ...

  2. Kotlin入门第三课:数据类型

    前文链接: Kotlin学习第一课:从对比Java开始 Kotlin入门第二课:集合操作 初次尝试用Kotlin实现Android项目 Kotlin的数据类型与Java类似,因此这篇文章主要看Kotl ...

  3. Spring入门第四课

    注入参数详解:null值和级联属性 可以使用专用的<null/>元素标签为Bean的字符串或其他对象类型的属性注入null值. 和Struts,Hiberante等框架一样,Spring支 ...

  4. 简单工厂模式(Java与Kotlin版)

    Kotlin基础知识的学习,请参考之前的文章: Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次尝试用Kotlin实现Android ...

  5. 设计模式(二)简单工厂模式(Simple Factory Pattern)

    一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式——简单工厂模式. 二.简单工厂 ...

  6. Java设计模式之工厂模式(简单工厂模式+工厂方法模式)

    摘自http://blog.csdn.net/jason0539/article/details/23020989 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是 ...

  7. C#设计模式之二简单工厂模式(过渡模式)

    一.引言 之所以写这个系列,是了为了自己更好的理解设计模式,也为新手提供一些帮助,我都是用最简单的.最生活化的实例来说明.在上一篇文章中讲解了单例模式,今天就给大家讲一个比较简单的模式--简单工厂模式 ...

  8. C#设计模式(2)——简单工厂模式(转)

    C#设计模式(2)——简单工厂模式   一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理 ...

  9. C#设计模式之简单工厂模式(过渡模式)

    一.引言 之所以写这个系列,是了为了自己更好的理解设计模式,也为新手提供一些帮助,我都是用最简单的.最生活化的实例来说明.在上一篇文章中讲解了单例模式,今天就给大家讲一个比较简单的模式——简单工厂模式 ...

随机推荐

  1. JAVA-Socket通信笔记

    JAVA - Socket 从开学到现在 也学了三个月时间的java了,一直在 在 语法和基本使用上周旋,井底之娃一枚. 这两天 有学长指点,花了两天的时间 学习了java多线程和socket的简单使 ...

  2. CachedRowSet使用

    public interface CachedRowSet extends RowSet,Joinable 所有标准 CachedRowSet 实现都必须实现的接口.Sun Microsystems ...

  3. PHP导出生成CSV文件

    composer 用起来是非常方便的 所以我是依赖composer来做的包管理 1.先安装composer 自行百度一下composer安装以及使用 2.用composer下载安装office包即可 ...

  4. 014 一对多关联映射 单向(one-to-many)

    在对象模型中,一对多的关联关系,使用集合来表示. 实例场景:班级对学生:Classes(班级)和Student(学生)之间是一对多的关系. 多对一.一对多的区别: 多对一关联映射:在多的端加入一个外键 ...

  5. 走进javascript——数组的那些事

    Array构造器 如果参数只有一个并且是Number类型,那么就是指定数组的长度,但不能是NaN,如果是多个会被当做参数列表. new Array(12) // (12) [undefined × 1 ...

  6. 深度解析PHP数组函数array_combine

    前些天写了一篇关于array_merge的函数解析. 今天来看一个新的函数array_combine() 此函数一共有两个参数,一个是合并后数组的键名,另一个为键值. 注意:合并后数组的键名放在第一个 ...

  7. 1089 Intervals(中文)

    开始前先讲几句废话:这个题我开始也没看懂,后来借助百度翻译,明白了大概是什么意思. 试题描述 输入一个n,然后输入n组数据,每个数据有两个数,代表这个闭区间是从几到几.然后看,如果任意两个闭区间有相重 ...

  8. PHP基础入门(二)---入门必备哦!

    前言 在上一章中,我们初步了解了PHP的网页基础和PHP的入门基础,今天继续给大家分享更多有关PHP的知识. 理论知识看起来可能比较枯燥一些,但是我们的实践(敲代码)毕竟离不开它. 只有理论与实践相结 ...

  9. Python内置函数进制转换的用法

    使用Python内置函数:bin().oct().int().hex()可实现进制转换. 先看Python官方文档中对这几个内置函数的描述: bin(x)Convert an integer numb ...

  10. 使用Mingw编译wxSqlite3-3.0.5

    最近在学习wxWidgets,而且官方也出了3.0版本,貌似还不错的样子,准备做个小程序来练手.中间需要用到数据库看到很多人推荐wxSqlite3就去下来看看,以下是我使用TDM-GCC 4.8.1( ...