抽象工厂模式 | 学习笔记

简介: 快速学习抽象工厂模式

开发者学堂课程【Scala 核心编程 - 进阶抽象工厂模式学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/610/detail/9134


抽象工厂模式


内容介绍:

一、基本介绍

二、抽象工厂模式应用实例

三、工厂模式小结


一、基本介绍

1)抽象工厂模式:定义了一个 trait 用于创建相关或有依赖关系的对象簇,而无需指明具体的类

2)抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。

3)从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进步的抽象)。

4)将工厂抽象成两层,AbsFactory (抽象工厂)和具体实现的工厂子类,可以将常规化的操作交给 AbsFactory。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。


二、抽象工厂模式应用实例

源码

项目结构

image.png

先做一个抽象工厂的 trait,里面声明了一个 create pizza,有很多的工厂去实现这个方法,比如北京的工厂就去实现北京的披萨,伦敦的工厂就去创建伦敦的披萨,这是第一个改进

第二个改进是在使用上做的改进,在订披萨的时候,不需要再区分是要订北京pizza还是伦敦披萨,因为工厂已经可以明确出来客户想要订购的披萨。

使用抽象工厂模式来完成披萨项目.

class BJFactory extends AbsFactory {

override def createPizza(t: String):

pizza.Pizza = {

var pizza: Pizza= null

if (tequals("cheese")) {

pizza = new BJCheesePizza

} else if (t equals("pepper")) {

pizza = new BJPepperPizza

}

return pizza

//还有一个LDFactory开发和BJFactory类似.

//声明一个特质,类似java的接口

trait AbsFactory {

//一个抽象方法

def createPizza(t : String ): Pizza

}

object PizzaStore extends App {

val orderPizza =

new OrderPizza(new BJFactory)

//val orderPizza =

// new OrderPizza(new LDFactory)

println("退出程序...")

}

//orderPizza, 当使用抽象工厂模式后,订购一个 Pizza思路

//1.接收一个子工厂实例,很据该工厂的创建要求去实例

现在是想要订购一个披萨,需要传递一个工厂出来,不管工厂是什么

把类型传给工厂,工厂就需要知道客户是想要什么类型的pizza,因为工厂已经明确知道是哪个地方的工厂,所以在订购披萨的时候,如果想要北京pizza就直接给北京工厂即可,这样就会显得更加简洁

class OrderPizza { //

var absF actory :AbsFactory =_

def this(absFactory: AbsFactory) {   (原先是传一个tap出来)

//多态

this

breakable {

var orderType: String = null

var pizza: Pizza = null

do {

printIn("请输入pizza的类型,使用抽象工厂模式..")

orderType = StdIn.readLine()

//使用简单工厂模式来创建对象.

pizza = absFactory.createPizza(orderType)

if (pizza == null){

break()

pizza.prepare()

pizza.bake()

pizza.cut()

pizza.box()

} while (true)

}}}

用的时候整个思路会变得不一样,当去订购披萨时会传一个工厂,但是是以抽象工厂来接收的,他可能是北京工厂,也有可能是伦敦工厂,所以使用abstract factory,可以体现出他的多态,用抽象工厂的名称调用create pizza

代码运行:import com . atguigu. chapter17. abstractfactory . pizzastore. pizza. {BICheesePizza,

BJPepperPizza, Pizza}

新建一个包,先写一个抽象工厂类出来,name为AbsFactory,Kind为Trait,随后新建各个地方的工厂,首先,新建一个北京工厂,这工厂需要去继承抽象工厂,然后引一下披萨,北京有胡椒披萨,奶酪披萨等等

//这时一个实现TAbsFacotory的个子工厂类

//如果希望订购北京的Pizza就使用该工厂子类

class BJFactory extends AbsFactory {

override def createPizza(t: String): Pizza = {

var pizza: Pizza = null

if (t. equals( "cheese")) {

pizza = new BICheesePizza

} else if (t.equals("pepper")) {

pizza = new BJPepperPizza

}

return pizza

}

object Pizzastore {

def main(args: Array[String]): Unit = {

new OrderPizza(new BJFactory)

//new Orderpizza(new LBFactory)

}

}

//orderPizza ,当使用抽象工厂模式后,订购个Pizza思路

//1.接收一个子工厂“实例,根据该工厂的创建要求去实例

object Pizzastore {

def main(args: Array [String]): Unit ={

new Orderpizza(new BJFactory)

}


三、工厂模式小结

1) 工厂模式的意义

将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。

2)三种工厂模式

简单工厂模式、工厂方法模式和抽象工厂模式

3)设计模式的依赖抽象原则

➢创建对象实例时,不要直接 new 类,而是把这个 new 类的动作放在一个工厂的方法中,并返回。

也有的书上说,变量不要直接持有具体类的引用,因为中间有一个缓冲层,会给一个编写业务逻辑的可能,如果直接new出来,那么就没有缓冲层,不能够进行优化、批量处理或者去做防范工作根本没有机会。代码的控制权交给了底层,就没有办法控制了。但是如果 new 一个工厂里面,在工厂里面是可以添加这些机制的。

➢不要让类继承具体类(依赖抽象),而是继承抽象类或者是trait (接口)

➢不要覆盖基类中已经实现的方法。覆盖和时间是两个概念,覆盖会出现一个问题就是,可能会造成不知道使用的是哪个这种现象

相关文章
|
Python
Python明确指定编码
【5月更文挑战第5天】
197 3
|
前端开发 JavaScript
js 打开资源管理器(经典范例:纯前端选择并预览图片)
js 打开资源管理器(经典范例:纯前端选择并预览图片)
215 0
|
JavaScript 前端开发 UED
扫码登录全过程
扫码登录全过程
245 2
|
存储 网络协议 安全
「译文」CMDB 最佳实践技术指南 -3-CMDB 应用映射 - 技术原理和最佳实践
「译文」CMDB 最佳实践技术指南 -3-CMDB 应用映射 - 技术原理和最佳实践
|
网络协议 物联网 Linux
WireGuard 系列文章(七):使用 WireGuard 和 Netmaker 创建 Full Mesh 网络
WireGuard 系列文章(七):使用 WireGuard 和 Netmaker 创建 Full Mesh 网络
|
NoSQL Java Redis
Spring Boot使用Redis的Lettuce连接池,隔一段时间再连接就报连接超时
Spring Boot使用Redis的Lettuce连接池,隔一段时间再连接就报连接超时
1844 0
|
存储 安全 编译器
02-📝C++核心语法|C++对C的扩展【::作用域运算符、名字控制、struct类型加强、C/C++中的const、引用(reference)、函数】
复习`C++核心语法`,且适当进行汇编探索底层实现原理,进一步夯实基础,为以后的`底层开发`、`音视频开发`、`跨平台开发`、`算法`等方向的进一步学习埋下伏笔。
02-📝C++核心语法|C++对C的扩展【::作用域运算符、名字控制、struct类型加强、C/C++中的const、引用(reference)、函数】
|
PHP
最新的PHP视频
PHP7越来越热,最近发现很多小伙伴都在自学PHP7,在网上找了很多的教程之后,陷入了误区,有的讲的知识点还算全面,但是老师讲课语言没有刺激性,听着听着就睡着了,有的讲的乱七八糟,非常的不系统,学完也不知道做什么。PHP7视频和PHP视频可以马上下载到哟
1293 0