设计模式有 23 种,按大类分的化可以分为三类
- 创建型(如:工厂模式、单例模式、原型模式等)
- 结构模式型(如:装饰器模式、代理模式)
- 行为型(如:观察者、迭代器模式等)
工厂模式又分为:工厂方法模式、抽象工厂模式、简单工厂模式
简单工厂模式
我们从最简单的开始。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例
类图:苹果和梨都是继承植物
代码
class Plant {
constructor(name) {
this.name = name
}
grow() {
console.log('我有生长功能哦~~')
}
}
class Apple extends Plant {
constructor(name, color) {
super(name)
this.color = color
}
}
class Pear extends Plant {
constructor(name, color) {
super(name)
this.color = color
}
}
new Apple('苹果', '红色')
new Pear('梨子', '黄色')
// 经典案例 jQuery
class jQuery {
constructor(selector) {
let elems = Array.from(document.querySelectorAll(selector))
let length = elems ? elems.length : 0
for (let i = 0; i <= length; i++) {
this[i] = elems[i]
}
this.length = length
}
html() {
}
}
window.$ = function (selector) {
return new jQuery
}
工厂模式的好处在于, 我们可以不动原逻辑的基础上, 继承和扩展新的功能, 这样我们就可以提高效率, 之前大神写的代码可以复用, 而且可以站在巨人的肩膀上, 不断扩展。 当然, 其实这些你们平时应该都有写过或者用过, 只是现在由一个名词规范起来, 是不是觉得突然高大尚了。 上面代码直接new 的缺点是, 耦合和依赖于具体的实现。
工厂模式方法
同先上一个类图, 需求变了需要添加个橘子:
上代码:
class Plant {
constructor(name) {
this.name = name
}
grow() {
console.log('growing~~')
}
}
class Apple extends Plant {
constructor(name, color) {
super(name)
this.color = color
}
}
class Orange extends Plant {
constructor(name, color) {
super(name)
this.color = color
}
}
class AppleFactory {
create() {
return new Apple('苹果', '红色')
}
}
class OrangeFactory {
create() {
return new Orange('橙子', '橙色')
}
}
const settings = {
'apple': AppleFactory,
'orange': OrangeFactory
}
let apple = settings['apple']().create()
let orange = settings['orange']().create()
这样写的好处我们可以随意添加不同的水果,我们不用关心如何实现,新增一个水果类,拿来用就好,还有一个好处就是,假如AppleFactory 有改动新增新的功能,但是引用的地方很多,我们只需要新增一个 AppleFactory,修改不影响老代码
抽象工厂模式
抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象.
为了好展示我们来举个例子:比如现在用java来写个软件要运行在不同系统window、mac等,但是他们的icon和button是不同的
类图
class Factory {
// 公共的方法是有一定的关联
createButton() {//创建按钮
}
createIcon() {// 创建图标
}
}
class Icon { }
class AppleIcon {
render() {
console.log(`绘制苹果图标`)
}
}
class WindowsIcon {
render() {
console.log(`绘制window图标`)
}
}
class Button { }
class AppleButton {
render() {
console.log(`绘制苹果按钮`)
}
}
class WindowsButton {
render() {
console.log(`绘制windows按钮`)
}
}
class AppleFactory extends Factory {
createButton() {//创建按钮
return new AppleButton();
}
createIcon() {// 创建图标
return new AppleIcon();
}
}
class WindowsFactory extends Factory {
createButton() {//创建按钮
return new WindowsButton();
}
createIcon() {// 创建图标
return new WindowsIcon();
}
}
/**
* Java是跨平台的
* 1.画一个图标
* 2.画一个按钮
*/
let windowsFactory = new WindowsFactory();
windowsFactory.createIcon().render();
windowsFactory.createButton().render();
//=========================================
let appleFactory = new AppleFactory();
appleFactory.createIcon().render();
appleFactory.createButton().render();
小结
- 简单工厂 一般就是一个函数返回产品的实例 (最常用,使用最多)
- 工厂方法 多了工厂类,要想创建产品,需要先创建此工厂的实例,再通过此工厂来创建产品。(少用)
- 在抽象工厂中,一个工厂可以创建多种产品 (基本不用) 看到这里了,你们的点赞是我动力~~
补充知识点-类图
- 用于描述系统中的对象类本身的组成和对象类之间的各种静态关系
- 类之间的关系:依赖、泛化(继承)、 实现、关联、聚合和组合 这里主要讲类图的依赖、泛化(继承)
依赖关系(Dependence)
只要在类中用到了对方,那么它们之间就存在依赖关系,如果没有对方,连编译都通过不了, 通俗的说就是 比如 动物 依赖于水和空气,下面为类图: 由三部分组成,类的名字、类的属性、类的方法。 依赖关系由虚线空心箭头表示
泛化关系(Generalization)
泛化关系实际上就是继承关系,他就是依赖关系的特例, 泛化关系由实线空心箭头表示