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代替if或者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. 适用场景

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

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

简单工厂模式(Java与Kotlin版)的更多相关文章

  1. 简单工厂模式--java代码实现

    简单工厂模式 工厂,生产产品的场所.比如农夫山泉工厂,生产农夫山泉矿泉水.茶π等饮料.矿泉水和茶π都属于饮料,都具有解渴的功能,但是每种饮料给人的感觉是不一样的.矿泉水和茶π在Java中相当于子类,饮 ...

  2. 简单工厂模式-Java篇

    简单工厂模式就是考虑如何实例化对象的问题,就是说到底要实例化谁,将来会不会增加实例化对象,比如计算器类中增加开根元素,应该考虑用一个单独的类来创造实例的过程,这就是工厂.下面将利用计算器类举例,解释简 ...

  3. SimpleFactoryPattern(简单工厂模式)-----Java/.Net

    工厂模式是最常用的一种创建型模式,通常所说的工厂模式一般是指工厂方法模式.本篇是是工厂方法模式的“小弟”,我们可以将其理解为工厂方法模式的预备知识,它不属于GoF 23种设计模式,但在软件开发中却也应 ...

  4. 工厂方法模式(Java与Kotlin版)

    前文推送 设计模式 简单工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次 ...

  5. 抽象工厂模式(Java与Kotlin版)

    前文推送 设计模式 简单工厂模式(Java与Kotlin版) 工厂方法模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操 ...

  6. 设计模式(Java版)-创建型模式之简单工厂模式

    前言:这段时间在学习设计模式,本人也是小菜一枚(所以写的如果有错误的地方请大大们给予指出).这个东西也是我一直想学习的,从点点滴滴做起,记录下自己每天的领悟! 一.工厂模式的动机 在软件系统中,经常面 ...

  7. 建造者模式(Java与Kotlin版)

    前文推送 设计模式 简单工厂模式(Java与Kotlin版) 工厂方法模式(Java与Kotlin版) 抽象工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比J ...

  8. Kotlin入门第四课:简单工厂模式

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

  9. 【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现

    一.什么是简单工厂模式 设计模式的核心是“分工”,通过分工将对象与职责划分的更细化,进而提升系统设计的可扩展性,使其更容易维护. 开闭原则:对扩展开放,对修改关闭:要增加一个新的处理逻辑,可以开一个新 ...

随机推荐

  1. jsp下载文件的实现方法及注意事项 (转)

    jsp中实现文件下载,最简单的方式是在网页上做超级链接,如:<a href="music/abc.mp3">点击下载</a>. 但是,这样服务器上的目录资源 ...

  2. DPI技术简介

    匹配模式 根据规则的特点,可以分为两种 特征字符串模式:特征字符串模式实现方法简单,将流量的特征字符串提取出来即可进行流识别,不过此种方式描述性较差,需要将流量特征进行遍历,才可以将流量全部识别出来, ...

  3. poj1328 Radar Installation(贪心 策略要选好)

    https://vjudge.net/problem/POJ-1328 贪心策略选错了恐怕就完了吧.. 一开始单纯地把island排序,然后想从左到右不断更新,其实这是错的...因为空中是个圆弧. 后 ...

  4. 10、jQuery初识

    jQuery是由原生js写的所以说所有jQuery制作出来的效果都可以使用js做出来,jQuery出现的目的是为了优化代码,提高码代码的效率它将很多功能封装. 本篇导航: jQuery的认识 jQue ...

  5. 《2019测试面试题-上海悠悠.pdf》

    前言 面试测试岗位一般会有笔试题,笔试题考SQL和编程基础比较多,小编最近收集了多家公司的测试面试题,整理成一个文档供大家参考. 2018年下半年一直不太平,听到最多的就是"p2p暴雷&qu ...

  6. VB编写的程序加入防火墙的例外中

    在工程中要先引入: NetCon 1.0 Type Library NetFwTypeLib Option Explicit Const NET_FW_SCOPE_ALL = 0 Const NET_ ...

  7. SharePoint 修改用户属性User Name

    前言 最近,碰到一个奇怪的事情,在SharePoint里的用户,如果显示方式显示为登录名(Account)的方式,显示为空.如下图: 1.经过查找,发现是因为用户属性 User name为空造成的,如 ...

  8. Unity项目中文字的统一管理

    一款游戏在研发初期就需要考虑多语言的问题,否则后期在进行多国语言版本时就面临着巨大的成本.鉴于之前页游的经验,其它同事设计出读取Excel的方式来管理所有的文字.但是我在使用中发现很致使的一个问题,当 ...

  9. thymeleaf学习笔记

    1.${@dict.hello().fatherName} 显示对象的属性2.${@dict.hello()[0].fatherName} 显示列表对象的属性3.<div th:object=& ...

  10. Kubernetes基础:Service

    本文的试验环境为CentOS 7.3,Kubernetes集群为1.11.2,安装步骤参见kubeadm安装kubernetes V1.11.1 集群 Service 介绍 我们通过Pod.Deplo ...