- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
简单工厂中我们通过参数来返回不同的产品对象,如果管理的对象过多,这个工厂函数会比较庞大,且当我们需要增加一个新的产品时,需要修改这个工厂方法,违反 开闭原则( 对拓展开放,对修改关闭 ).
为了解决简单工厂模式的问题,出现了工厂方法模式.
简单工厂类图关系类似如下:
如上图当我们需要增加一个产品时,我们需要修改create 方法增加相关判断的逻辑,这不符合开闭原则.
假如一个工厂只负责他自己的产品,那么新增产品也只是新增一个工厂以及对应的产品,那么简单工厂的问题是不是也解决了.
总结: 将对象的创建与实例化延迟到子类,这样的工厂设计就符合“开闭原则”了,扩展时不必去修改原来的代码 .
如上图当我们增加一个产品时,只需要增加一个工厂(实现抽象类),然后在各自的工厂返回自己需要的产品即可; 。
工厂方法由4个要素组成:
。
如果只是接触了js,可能对抽象不太了解 ,其实抽象只是一种思考的问题的方式.
抽象的定义是从 众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程 .
简单的理解其实就是 共有的特征、特性 ,比如我们要规范人这个对象具有的特点,就用一个接口或者抽象类声明一些共有的属性、方法,具体的子类在实现这个接口或者抽象类,这样子类也有这些属性、方法.
这样做的好处就是约束子类,保证子类都有这些属性、方法,不会存在乱七八糟的对象,这也符合我们大脑工作方式.
工厂方法是将 实际创建对象的工作推迟到子类 中,这样核心类就变成了 抽象类 。但是在JavaScript中很难像传统面向对象那样去实现创建抽象类。所以在JavaScript中我们只需要参考它的核心思想即可。我们可以将工厂方法看作是一个实例化对象的工厂类。虽然ES6也没有实现 abstract ,但是我们可以使用 new.target 来模拟出抽象类。 new.target 指向直接被new执行的构造函数,我们对new.target进行判断,如果指向了该类则抛出错误来使得该类成为抽象类.
ts 扩展了js,所以这里我用ts 来模拟 。
/*
工厂方法是简单工厂的优化版本,在之前把生成具体产品的实例逻辑都写在了工厂方法中,
导致增加一个产品,这个工厂方法需要修改。
所以工厂方法主要是把这一部分功能独立出来了,一个工厂负责一个产品
工厂方法核心结构有四个角色
1、抽象工厂
2、具体工厂
3、抽象产品
4、具体产品
因为js不支持没有抽象类这里用ts 代替,只要符合核心思想即可
*/
// 抽象工厂
abstract class CardFactor{
abstract getCardInstance(name:string, time:string):Card
}
// 抽象产品
abstract class Card {
carName: string;
time: string;
abstract getCarDesc():void
}
// 具体产品-BydCar
class BydCar extends Card {
constructor (name, time) {
super()
this.carName = name
this.time = time
}
runCarName () {
console.log(this.carName)
}
getCarDesc () {
console.log(`我是${this.carName},生产于:${this.time}`)
}
}
// 具体产品-JeepCar
class JeepCar extends Card {
constructor (name, time) {
super()
this.carName = name
this.time = time
}
runCarName () {
console.log(this.carName)
}
getCarDesc () {
console.log(`我是${this.carName},生产于:${this.time}`)
}
}
// 具体产品-BenzCar
class BenzCar extends Card {
carName: string
time: string
constructor (name, time) {
super()
this.carName = name
this.time = time
}
runCarName () {
console.log(this.carName)
}
getCarDesc () {
console.log(`我是${this.carName},生产于:${this.time}`)
}
}
// 具体的工厂-BydCarFactory
class BydCarFactory extends CardFactor {
getCardInstance (name, time) {
return new BydCar(name, time)
}
}
// 具体的工厂-JeepCarFactory
class JeepCarFactory extends CardFactor{
getCardInstance (name, time) {
return new JeepCar(name, time)
}
}
// 具体的工厂-BenzCarFactory
class BenzCarFactory extends CardFactor{
getCardInstance (name, time) {
return new BenzCar(name, time)
}
}
// test 直接使用具体的工厂
const bydCar = new BydCarFactory().getCardInstance('byd 汽车', '2022-08-20')
const jeepCar = new JeepCarFactory().getCardInstance('jeep 汽车', '2022-08-21')
const benzCar = new BenzCarFactory().getCardInstance('benz 汽车', '2022-08-22')
bydCar.runCarName()
bydCar.getCarDesc()
jeepCar.runCarName()
jeepCar.getCarDesc()
benzCar.runCarName()
benzCar.getCarDesc()
如果我们现在需要增加一种车型,那我们只需增加对应的工厂,跟产品类即可,我们 对原有的工厂不会造成任何影响 所谓的“对拓展开放,对修改封闭”就这么圆满实现了.
在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式.
上面代码中我们的比亚迪工厂只是生产一种产品,现实是一个工厂大概率是要生产很多种不同的产品,如比亚迪有汉dmi、dmp、唐suv等车型。这种一个工厂需要多种产品的时候,按照工厂方法的思路,我们需要写很多个这种工厂类,这也非常繁琐.
我们需要的是 一个工厂可以生产多种不同的产品对象 ,按照设计模式的思路 把变化的抽出来封装 。变的是 一个工厂可以支持多个产品对象,不变的依旧是在工厂中拿到产品对象 。按照工厂方法的思路,只需要在抽象工厂中增加创建对应的产品即可,以之前汽车的例子把工厂方法改成抽象工厂,只要把抽象工厂中增加对应的获取产品,修改之后现在比亚迪工厂支持默认车型,汉车型,suv车型; 。
/*
抽象工厂:一个工厂可以生产多种不同的产品,它思路跟工厂方法基本一致。
抽象工厂核心结构有四个角色
1、抽象工厂
2、具体工厂
3、抽象产品
4、具体产品
因为js不支持没有抽象类这里用ts 代替,只要符合核心思想即可
*/
// 抽象工厂
abstract class CardFactor{
// 默认的车型
abstract getCardInstance(name:string, time:string):Card
// 汉车型
abstract getCardHanDmiInstance(name:string, time:string):Card
// suv 车型
abstract getCardSuvInstance(name:string, time:string):Card
}
// 抽象产品,同理:这里也可以把产品进一步抽象,如汉的抽象产品,suv的抽象产品,这里不在调整
abstract class Card {
carName: string;
time: string;
abstract getCarDesc():void
}
// 具体产品-BydCar
class BydCar extends Card {
constructor (name, time) {
super()
this.carName = name
this.time = time
}
runCarName () {
console.log(this.carName)
}
getCarDesc () {
console.log(`我是${this.carName},生产于:${this.time}`)
}
}
// 具体产品-BydHanCar
class BydHanCar extends Card {
name = '中大型轿车汉'
desc = '这是来自比亚迪的汉'
constructor () {
super()
}
runCarName () {
console.log(this.carName)
}
getCarDesc () {
console.log(`我是${this.carName},生产于:${this.time}`)
}
}
// 具体产品-BydSuvCar
class BydSuvCar extends Card {
name = 'suv'
desc = '这是来自比亚迪的suv'
constructor () {
super()
}
runCarName () {
console.log(this.carName)
}
getCarDesc () {
console.log(`我是${this.carName},生产于:${this.time}`)
}
}
// 具体的工厂-BydCarFactory
class BydCarFactory extends CardFactor {
// 生产默认的byd 车型
getCardInstance (name, time) {
return new BydCar(name, time)
}
// 生产byd汉车型
getCardHanDmiInstance () {
return new BydHanCar()
}
// 生产byd suv车型
getCardSuvInstance () {
return new BydSuvCar()
}
}
// test 直接使用具体的工厂
const bydCarFactory = new BydCarFactory()
// 现在这个工厂具备生产三种车的产品了
const bydCar = bydCarFactory.getCardInstance('默认车型', '2023-3-7');
const hanCar = bydCarFactory.getCardHanDmiInstance();
const suvCar = bydCarFactory.getCardSuvInstance();
抽象工厂模式与 工厂方法 模式区别在于,工厂方法模式针对的是一个产品等级结构,而 抽象工厂 模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 .
抽象工厂模式同工厂方法模式一样,也是由4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同.
这种管理多个产品结构的抽象类,就是抽象工厂模式,让一个工厂具备管理多个产品结构.
抽象工厂模式相对于 工厂方法模式 来说 ,工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类 ,而抽象工厂模式是多个产品系列一个工厂类.
定义:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类.
抽象工厂模式与工厂方法模式区别在于, 工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构 ,一个工厂结构可以负责多个不同产品等级结构中的产品对象的创建 .
(1)工厂方法只有一个抽象产品类和一个抽象工厂类,可以派生出多个具体产品类和具体工厂类, 每个具体工厂类只能创建一个具体产品类的实例 .
(2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类, 同 时每个具体工厂类可以创建多个具体产品类的实例 .
如果您觉得阅读本文对您有帮助,请点一下 推荐 按钮,您的 推荐 将是我最大的写作动力,欢迎各位转载!
最后此篇关于创建型:工厂模式-工厂方法、抽象工厂的文章就讲到这里了,如果你想了解更多关于创建型:工厂模式-工厂方法、抽象工厂的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我应该执行以下操作: 可能通过服务/工厂,使用 $q(异步)查询 API 以获取大型名称数据集 有另一个服务(也是异步的),它应该只返回上述工厂的元素,如果它们与某个字符串(搜索字段)匹配。目的是缩小
我有一个通用的基类。我有一个实现基类的具体类。 我将如何创建工厂类/方法来交付不同类型的具体类? 举个例子: public class ReceiverBase where T : IInte
我正在查看以下链接中的 Ninject Factory 扩展: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-intro
工厂、提供商和服务这三个术语之间有什么区别? 刚刚了解 NHibernate 及其存储库模式(POCO 类等)。 最佳答案 工厂:通过将一堆位组合在一起或基于某种上下文选择类型来组装类 Provide
使用CGLIB我可以做到 final var enhancer = new Enhancer(); enhancer.setUseCache(false); enhancer.setSuperclas
我试图在 Kotlin 中使用伴随对象工厂方法(相当于 Java 中的静态工厂方法)创建一个嵌套内部类。这是我的代码的简化版本。 class OuterClass { var myData:L
我正在为我的大学做一个项目,但遇到了问题。 基本上,该项目由一个客户端-服务器应用程序组成,我想创建一个用于通信的 Packet 类。数据包由 header 和主体组成。现在问题来了。我可以有一些不同
这个问题在这里已经有了答案: Why doesn't polymorphism work without pointers/references? (6 个答案) What is object sl
我正在制作一个套接字工厂。我希望每个外部应用程序都使用 Socket 类的接口(interface),它是几个类(ServerSocketTCP、ClientSocketTCP、ServerSocke
我是 angularjs 的新手,我正在尝试创建一个小型电影数据库。这是我第一次使用工厂,我想确保这是正确的方法,以及如何在另一个功能中使用这个工厂,如下所示? 我希望这个工厂只运行一次,这样我就可以
这个问题在这里已经有了答案: Java inner class and static nested class (28 个答案) 关闭 5 年前。 public class DataFactory
我看过很多关于 C++ 工厂的帖子,但到目前为止我还没有看到解决我的问题的解决方案。 (虽然我可能遗漏了一些东西。) 示例控制台应用程序: #include #include #include
这是一个简单的 C++ 项目,有 2 种设计模式:单例和工厂,sigleton 也是一个模板化类,一个接口(interface) (IHash) 和一个类 (Hash1)。一个简单的工厂类 (Hash
这个问题类似于Factory and generics ,并且可能有相同的答案,但它是不同的。我有一个通用基类,它将由完全独立的 JAR 中的类进行扩展。所述 JAR 应该能够在不更改任何其他代码的情
问题是我需要为传递的类创建一个新实例 有没有办法重写这个函数,让它可以接受任意数量的参数? function createInstance(ofClass, arg1, arg2, arg3, ...
我想用简单的 C++ 语法创建一个简单的工厂方法: void *createObject(const char *str,...) { if(!strcmp("X",str)) retu
经过大约 10 个月的程序化 PHP 学习后,我现在正尝试着手研究基本的 OOP 原则和设计模式。这是一个爱好,我没有那么多时间去追求它,所以请原谅这个问题的水平很低。 我的网站(目前 100% 程序
我有一个简单的问题。 我如何编写一个工厂来定义使用 make() 或 create() 的关系,具体取决于原始调用 make() 还是 create()? 这是我的用例: 我有一个简单的工厂 /**
我正在尝试在延迟加载模块中提供 APP_BASE_HREF 注入(inject) token ,然而,工厂方法根本没有被调用。 在这里https://github.com/MaurizioCascia
我有以下 ast: import { factory as f } from 'typescript' const typeDeclaration = f.createTypeAliasDeclara
我是一名优秀的程序员,十分优秀!