简单工厂模式(Java与Kotlin版)
Kotlin基础知识的学习,请参考之前的文章:
学习一门语言,没有必要掌握全部特性才去实践。入门之后可以开始阅读好的开源项目代码,自己动手实现一些简单的案例,有困难再去补充学习相关的知识点,这样反复的过程效果会比较好。
最近在重新学习设计模式,正好用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版)的更多相关文章
- 简单工厂模式--java代码实现
简单工厂模式 工厂,生产产品的场所.比如农夫山泉工厂,生产农夫山泉矿泉水.茶π等饮料.矿泉水和茶π都属于饮料,都具有解渴的功能,但是每种饮料给人的感觉是不一样的.矿泉水和茶π在Java中相当于子类,饮 ...
- 简单工厂模式-Java篇
简单工厂模式就是考虑如何实例化对象的问题,就是说到底要实例化谁,将来会不会增加实例化对象,比如计算器类中增加开根元素,应该考虑用一个单独的类来创造实例的过程,这就是工厂.下面将利用计算器类举例,解释简 ...
- SimpleFactoryPattern(简单工厂模式)-----Java/.Net
工厂模式是最常用的一种创建型模式,通常所说的工厂模式一般是指工厂方法模式.本篇是是工厂方法模式的“小弟”,我们可以将其理解为工厂方法模式的预备知识,它不属于GoF 23种设计模式,但在软件开发中却也应 ...
- 工厂方法模式(Java与Kotlin版)
前文推送 设计模式 简单工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次 ...
- 抽象工厂模式(Java与Kotlin版)
前文推送 设计模式 简单工厂模式(Java与Kotlin版) 工厂方法模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操 ...
- 设计模式(Java版)-创建型模式之简单工厂模式
前言:这段时间在学习设计模式,本人也是小菜一枚(所以写的如果有错误的地方请大大们给予指出).这个东西也是我一直想学习的,从点点滴滴做起,记录下自己每天的领悟! 一.工厂模式的动机 在软件系统中,经常面 ...
- 建造者模式(Java与Kotlin版)
前文推送 设计模式 简单工厂模式(Java与Kotlin版) 工厂方法模式(Java与Kotlin版) 抽象工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比J ...
- Kotlin入门第四课:简单工厂模式
Kotlin基础知识的学习,请参考之前的文章: Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次尝试用Kotlin实现Android ...
- 【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现
一.什么是简单工厂模式 设计模式的核心是“分工”,通过分工将对象与职责划分的更细化,进而提升系统设计的可扩展性,使其更容易维护. 开闭原则:对扩展开放,对修改关闭:要增加一个新的处理逻辑,可以开一个新 ...
随机推荐
- django的templatetags
创建tag方式,首先在需要使用tag的app下创建一个templatetags的python包, 然后在包里创建一个tag模块,例如hellotag.py from django import tem ...
- Java利用ShutDownHook关闭系统资源
Java关闭钩子 在Java程序中能够通过加入关闭钩子,实如今程序退出时关闭资源的功能. 使用Runtime.addShutdownHook(Thread hook)向JVM加入关闭钩子 public ...
- Spark2.3(四十):如何使用java通过yarn api调度spark app,并根据appId监控任务,关闭任务,获取任务日志
背景: 调研过OOZIE和AZKABA,这种都是只是使用spark-submit.sh来提交任务,任务提交上去之后获取不到ApplicationId,更无法跟踪spark application的任务 ...
- CentOS7 使用yum命令安装Java SDK(openjdk)
CentOS 6.X 和 7.X 自带有OpenJDK runtime environment (openjdk).它是一个在linux上实现开源的java 平台. 安装方式: 1.输入以下命令,以 ...
- 树莓派raspberry pi配置无线路由器AP
raspi-config进入系统配置面板 进行 Expand Filesystem 扩展文件系统否则备份系统的时候备份文件会急速膨胀. (1)配置网络环境nano /etc/network/inte ...
- bootstrap响应式前端页面
技术:HTML+CSS+JS+bootstrap 概述 这套代码响应式前端页面基本写完了,适合初学前端的同学,里面主要运用了HTML+CSS布局和动画,js逻辑较少,页面都是静态,未接入接口.响应 ...
- (原)caffe中的conv
转载请注明出处: https://www.cnblogs.com/darkknightzh/p/10486686.html conv总体调用流程如下图所示: 说明:带o的为输出,如Wo代表输出宽度:带 ...
- GPL、BSD、MIT、Mozilla、Apache、LGPL开源协议介绍
BSD开源协议 BSD开源协议是一个给于使用者很大自由的协议.基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布. 但”为所欲为”的前提当你发布使 ...
- 【C#】解析C#中管道流的使用
目录结构: contents structure [+] 匿名管道(anonymous pipe) 命名管道(named pipe) 管道为进程间通信提供了一种可能.管道分为两种,一种是匿名管道,另一 ...
- Linux将yum源设置为阿里云的镜像源
第一步:备份原有镜像源 mv /etc/yum.repo.d/Centos-Base.repo /etc/yum.repo.d/Centos-Base.repo.bak 第二步:下载阿里云的镜像源 w ...