#explainlikeimfiveThe Three Little Creational Patterns – 一个设计模式介绍
对于程序员来说,设计模式至关重要,至少对我而言。这些是常见问题的既定解决方案,有助于保持代码可维护和松散耦合。越了解它们,就越容易解决我们面临的所有问题。
一旦你学会它们,你就会到处看到它们。我使用适配器连接API,用于Ember服务的单例,用于管理UI的状态和观察者,以及用于管理对象和在假期欺骗我的亲戚的外观。
然而,作为一个没有计算机科学背景的人,学习它们是一场斗争。每个解释或书都充满了行话来筛选。其中一些我还是不太明白。我几乎不知道Flyweight模式是如何工作的,任何说他们做的人都是骗子。
所以我的想法是用故事解释设计模式。故事也很成熟并解决了常见问题,但更容易理解。那就是童话故事
将设计模式简介为童话故事
本系列旨在帮助人们学习设计模式的基本功能和用途。这些例子很简单,也是学习更多内容的起点。它们也使用JavaScript,但这些想法适用于任何面向对象的语言。
在这里,我将看看五种创作设计模式。这些是用于创建和管理更易于维护且副作用更少的对象的模式。
当谈到创造事物时,我会想到三只小猪让我们开始。
用工厂建造稻草屋
在这个童话版本中,让我们说每只小猪都在闯入房地产市场。当然,第一只猪通过制作稻草房来做到这一点。他决定用JavaScript类创建它们。
猪写了这个基地用于制作稻草屋。它需要的唯一论据是所需的稻草包数量。
类 StrawHouse { 构造函数(稻草) { 这个。稻草 = 稻草; } }
随着订单的进入,猪意识到这个级别对于制造大量房屋效率不高。客户给他他们想要的房子的高度,如果他们想要用更多的稻草加固房子。猪每次都要做数学,有时候不止一次做同样的操作。
以这种方式创建如此多的房屋实例令人筋疲力尽,因此猪使用工厂模式来管理制作每个房屋实例的工作。
类 StrawHouseFactory { 静态的 创建(高度, 眼镜) { 常量 strawBase = (眼镜 === “增强”) ? 350 : 150, amountOfStraw = 高度 * strawBase; 返回 新 StrawHouse(amountOfStraw); } }
这个稻草屋工厂让他快速创建一个不同的稻草屋从信息客户给他,做数学并返回所需的 StrawHouse
类实例。这是一个简单但强大的好处,这是有道理的,因为工厂可以说是最简单的创造模式。
常量 smallStrawHouse = StrawHouseFactory。创建(10) strongStrawHouse = StrawHouseFactory。创建(25, “增强”);
作为奖励,房屋类和工厂类没有太紧密地联系在一起。他可以很容易地改变任何一个班级而不会打破另一个班这是你在其他创作模式中看到的共同利益,甚至是所有设计模式。
用原型建造一个棒屋
第二头猪正在制作棍子房,但面临着不同的问题。他的所有客户都希望用类似的棒屋建立社区。他可以尝试他兄弟用于稻草房的工厂方法,但他会一遍又一遍地制作相同类型的棍子屋。编写代码来生成相同的实例是重复的,他想要更高效的东西。
第二只猪使用Prototype模式。让我们说一群客户都想要一个小棍子屋。他不会为他们制作多个棍子实例,而是只制作一个(原型)并包含一个根据需要复制它的方法。
类 StickHousePrototype { 构造函数(枝, 高度) { 这个。高度 = 高度; 这个。枝 = 高度 * 100; } 复制() { 返回 新 StickHouse(这个。枝, 这个。高度); } addMailbox(材料) { 这个。邮箱 = 材料 } }
这样重复性较低,并确保每一个都完全相同。他甚至可以对每个副本进行更改以获得额外的灵活性。
常量 smallStickHouse = 新 StickHousePrototype(15) largeStickHouse = 新 StickHousePrototype(50); 常量 housesForFriends = { “艾米”: smallStickHouse。复制(), “鲍勃”: smallStickHouse。复制(), '油菜': smallStickHouse。复制()。addMailbox('木') 'Dingus': largeStickHouse。复制(), “龙骑士”: largeStickHouse。复制()。addMailbox('秤') }
总的来说,如果您需要大量完全或大致相同的实例,则此模式最有效。
用生成器建造砖房
第三头猪卖砖房,这是一个更雄心勃勃的目标。砖房比较复杂,需要几步。此外,由于他们在森林中的新鲜感,客户经常推迟决定它应该有多大,直到中途。第三只猪意识到他需要一种能够处理所有这些额外复杂性的模式,而不会让人不知所措。
他偶然发现了Builder模式,他的小猪祈祷得到了解答
这是制作砖房的第三个猪的基地。它需要三个尺寸的尺寸和水泥的量来将砖块粘在一起。
类 BrickHouse { 构造函数(宽度, 长度, 高度, 水泥) { 这个。宽度 = 宽度; 这个。长度 = 长度; 这个。高度 = 高度; 这个。水泥 = 水泥; } }
猪然后写他的Builder类。他想要的主要内容是:
- 设置每个尺寸标注的单独方法。构建器应该能够占用一些,暂停运行其他代码,然后从中断处继续。
- 一旦知道完整尺寸,计算需要多少水泥的方法。
- 获取所有这些信息并返回完成的砖房的最终方法。
类 BrickHouseBuilder { 构造函数() { 这个。brickHouse = 新 BrickHouse(); } 宽度(宽度) { 这个。brickHouse。宽度 = 宽度; } 长度(长度) { 这个。brickHouse。长度 = 长度; } 高度(高度) { 这个。brickHouse。高度 = 高度; } addCement() { 这个。brickHouse。水泥 = 这个。getCementBase() + 这个。getCementForBetweenBricks(); } floorSize() { 返回 这个。brickHouse。宽度 * 这个。brickHouse。长度 } getCementForBetweenBricks() { 返回 getFloorSize() * 0.25; } getCementBase() { 返回 这个。getFloorSize() * (这个。brickHouse。高度 / 五); } 建立() { 返回 这个。brickHouse; } }
我知道,要吸收很多东西。但是要知道猪可以用所需的任何数据调用每种方法来仔细地建造每个房子。
常量 newBrickHouse = 新 BrickHouseBuilder(), smallBrickHouse = newBrickHouse。宽度(五)。长度(五)。高度(五)。addCement()。建立();
当他必须暂停代码中的构造时,它也可以工作。
常量 largeBrickHouse = newBrickHouse。宽度(20)。长度(25); //在此处进行额外计算,因为客户决定要做什么 largeBrickHouse。高度(20)。addCement()。建立();
正如您所看到的,构建器非常适合抽象出更大的对象和多个语句所需的更复杂的步骤和计算。
用Singleton建立业务
让我们快速将这个童话故事推向未来。这三头小猪遇到了大坏狼,他们都组成了一家名为Pigs and Wolf Partners Real Estate LLC的房地产公司。这是一家伟大的新公司,他们希望用JavaScript管理他们的公司信息。
三只猪意识到他们不能使用之前的任何模式,因为它们是为一个类的多个实例而制作的。他们公司只有一个实例,因此只有该类的一个实例。否则,崇拜房地产动物可能会试图复制并超越他们一生的工作
这就是单身人士闪耀的地方。设置单身人士,因此只能制作一个实例。任何创建新的尝试都会返回原始版本。
类 房地产公司 { 构造函数(雇员) { 如果 (类型 房地产公司。例 === '宾语') { 返回 房地产公司。例; } 房地产公司。例 = 这个; 这个。雇员 = 雇员; 返回 这个; } }
下面你会看到有人试图制作公司的两个实例,第二个是假冒其他不同的野生动物。
常量 公司 = 新 房地产公司(('猪1', '猪2', '猪3', '狼')), fakeCompany = 新 房地产公司(('斑马', “土豚”, '克里斯普拉特'))
因为它是一个单身人士, fakeCompany
将返回相同的 公司
。然后猪可以在他们的程序中的任何地方引用他们真实的公司并获得原始实例,包括在其他地方对其进行的任何更改。适当的单身人士是可靠的“单一事实来源”。
如果你想了解更多,我在这里写了一个更实用的,与口袋妖怪相关的单身人士用法。
Eevees,Quizzes和Singletons,哦,我的
Max Antonucci·5分钟阅读
#javascript #烬 #showdev
用抽象工厂超越住房市场
这些猪一切都适合他们。他们在市场上有三种类型的房子,他们有一家公司,他们每个人都有私人泳池和稳定的女朋友,他们希望有一天能够结婚。他们还有一件事就是大规模的解体。
为了制作他们所有的房子,猪需要管理很多创作模式:
- 稻草房的工厂
- 棒屋的原型制造商
- 砖房的建造者。
值得庆幸的是,有一个最后的创作模式来管理它们:抽象工厂
当常规工厂创建单个类的实例时,抽象工厂会处理多个类的实例。猪需要管理的不是一个,而是三个。抽象工厂可以调用他们需要的任何类,甚至可以添加一些额外的逻辑来涵盖常见的用例。
类 PigHouseAbstractFactory { 静态的 strawHouse(尺寸) { 如果 (尺寸 === '大') { StrawHouseFactory。创建(25, 真正); } 其他 { StrawHouseFactory。创建(10) } } 静态的 stickHouse(尺寸) { 如果 (尺寸 === '大') { 返回 新 newStickHousePrototype(50)。复制(); } 其他 { 返回 新 newStickHousePrototype(15)。复制(); } } 静态的 brickHouse(尺寸) { 如果 (尺寸 === '大') { 返回 新 BrickHouseBuilder。宽度(20)。长度(25)。高度(20)。高度(20)。getCement()。建立(); } 其他 { 返回 新 BrickHouseBuilder。宽度(五)。长度(五)。高度(五)。getCement()。建立(); } } }
这种模式允许它们填充从单个类开始的任何顺序,并且不会过于紧密地耦合任何依赖类。
常量 smallStrawHouse = PigHouseAbstractFactory。strawHouse(), largeStrawHouse = PigHouseAbstractFactory。strawHouse('大') smallStickHouse = PigHouseAbstractFactory。stickHouse(), largeStickHouse = PigHouseAbstractFactory。stickHouse('大') smallBrickHouse = PigHouseAbstractFactory。brickHouse(), largeBrickHouse = PigHouseAbstractFactory。brickHouse('大');
看起来猪在这个童话故事中有一个美好的结局,房地产的未来也很光明。
设计模式任务只有开始
我希望在本系列中涵盖所有23种经典的Gang of Four设计模式。这些帖子绝不是你需要了解的全部内容,但我希望它们可以作为学习每个人复杂性的简单基础。在学习它们时我努力寻找适合初学者的介绍,并希望这些帮助其他人避免同样的命运。
未完待续…
封面图片由SafeBooru.org提供