-
【关系理论高手请进!】为什么说关系子模式是采用数据定义语言来实现的?不是用数据查询语言么?
2013-05-23 16:02:15【关系理论高手请进!】为什么说关系子模式是采用数据定义语言来实现的?不是用数据查询语言么? [img=https://img-bbs.csdn.net/upload/201305/23/1369296125_302460.jpg][/img] -
JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖
2016-05-23 22:35:19什么是设计模式? JAVA当中有23种设计模式,解决某一问题最有效的方法单例设计模式 解决一个类在内存中只存在一个对象 想要保证对象唯一该怎么做》1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类...JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖
java也越来越深入了,大家加油吧!咱们一步步来
一.单例设计模式
什么是设计模式?
JAVA当中有23种设计模式,解决某一问题最有效的方法
单例设计模式
解决一个类在内存中只存在一个对象
想要保证对象唯一该怎么做》
- 1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
- 2.还为了让其他程序访问到该类对象,只好在本类中自定义一个对象
- 3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
这三步怎么怎么实现呢?
- 1.将构造函数私有化
- 2.在类中创建一个本类对象
- 3.提供一个方法可以获取到该对象
然后我们的代码就出来了
/** * 单例模式 * * @author LGL * */ public class Single { // 将构造函数私有化 private Single() { } // 在类中创建一个本类对象 private static Single s = new Single(); // 提供一个方法可以获取到该对象 public static Single getInstance() { return s; } }
当然,我们还有一种写法——懒汉式
/** * 单例模式 * 懒汉式 * @author LGL * */ public class Single { private static Single s = null; public Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { if (s == null) s = new Single(); return s; } }
也有这么一种写法
/** * 单例模式 * 饿汉式 * * @author LGL * */ public class Single { private static Single s = new Single(); public Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { return s; } }
单例模式的写法多种多样,只要掌握这个思想就可以了
饿汉式的特点:single类一进内存就已经创建好了对象
懒汉式的特点:对象是方法被调用时才初始化,也叫作对象的延迟加载Single类进内存还没有存在,只有调用了getInstance()方法时才建立对象,这就叫做延迟加载
我们一般用饿汉式,因为他安全,简单
二.继承
面向对象的思想中的一个思想,继承,我们可以这样去理解,我们可以定义一个学生类,他有名字和年龄,还有一个学习的方法
/** * 学生 * @author LGL * */ class Student { String name; int age; void study() { System.out.println("学习"); } }
然后我们可以再定义一个工人类
/** * 工人 * @author LGL * */ class Worker { String name; int age; void work() { System.out.println("工作"); } }
他同样有名字和年龄还有一个工作的方法
这个时候我们可以发现,他们都存在相同的关系,他们都是人,人都具备年龄和姓名,所以我们可以将学生和工人的共性提取出来描述,只要让学生和工人与单独描述的类有关系就行,也就是继承
/** * 人 * * @author LGL * */ class Person { String name; int age; }
这个Person就叫做父类,超类,基类
然后我们的工人和学生就可以这样去写
/** * 学生 * * @author LGL * */ class Student extends Person { void study() { System.out.println("学习"); } } /** * 工人 * * @author LGL * */ class Worker extends Person { void work() { System.out.println("工作"); } }
他们是Person的子类,继承是源于生活,所以工人不能继承学生,没有伦理性,千万不要为了获取其他类的功能,简化代码而继承,必须是类与类之间有所属关系才可以继承,is a 的关系
继承的优点- 1.提高代码的复用性
- 2.让类与类之间产生关系,有了这层关系才有了多态的特性
JAVA语言中,java只支持单继承,不支持多继承
- 为什么不能多继承?
因为多继承容易带来安全隐患,当多个父类中定义了相同的功能,当功能内容不同时,子类对象不确定运行哪一个,但是JAVA保留了这种机制,并用另一种体现形式来表示,多实现。
JAVA支持多层继承,也就是一个继承体系如何使用一个继承体系的功能?
想要使用体系,先查阅体系中父类的描述,因为父类中定义的是该体系中的共性内容,通过了解共性功能就可以知道该体系的基本功能,那么,这么体系已经可以基本使用了。
那么集体调用时,要创建最子类的对象,为什么?一是因为有可能父类不能创建对象,二是创建子类对象可能使用更多的功能,包括基本的也包括特有的
简单的说一句:查阅父类功能,创建子类对象使用功能
三.聚集关系
这个概念可能很多人不是很熟悉,确实我们实际开发当中很少提到,我们对象和对象之间,不光有继承关系,还有组合关系,
聚合
球员是球队中的一个,球队中有球员,这就是聚合关系
组合
手是人身体的一部分,腿是身体的一部分,这就是组合关系,你说这和聚合没什么不同,那你就错了,要知道,球队少了个球员没事,人少胳膊少腿就有事哦,所以组合关系更加紧密一点
都是吧对象撮合在一起,像我们继承是秉承一个is a的关系,而聚集是has a的关系,谁里面有谁
这个关系我们就不多做赘述了
我们关系讲完了,现在应该可以用代码去表示表示了,这里我就用当继承关系时,子类和父类之间的变量关系来举例
四.子父类变量关系
我们来探索一下子父类出现后,类成员的特点
- 变量
- 2.函数
- 3.构造函数
我们一步步来分析
1.变量
我们撸一串代码
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); System.out.println("num1 = " + z.num1 + "\n" + "num2 = " + z.num2); } } /** * 父类 * * @author LGL * */ class Fu { int num1 = 4; } /** * 子类 * * @author LGL * */ class Zi extends Fu { int num2 = 5; }
这样,是不是很容易知道输出的结果
但是我们那会这么简单,我们还有特殊情况
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); System.out.println("num1 = " + z.num + "\n" + "num2 = " + z.num); } } /** * 父类 * * @author LGL * */ class Fu { int num = 4; } /** * 子类 * * @author LGL * */ class Zi extends Fu { int num = 5; }
当子类和父类都有相同的变量的时候,现在该打印什么呢?
没错,打印了子类的值,为什么?因为输出的num前面其实默认带了一个this,如果我们要打印父类的值,需要加super,这是一个新的关键字了
void show(){ System.out.println(super.num); }
结果显而易见了
所以变量的特点:如果子类中出现非私有的同名成员变量时,子类要访问本类中的成员变量,用this,子类访问父类中的同名变量,用super,this和super的使用几乎一致,this代表的是本类对象的引用,super代表父类对象的引用
不过我们也不会这么蛋疼在父类创建又在子类创建,我们来看第二个
2.函数
也就是方法,我们正常的应该是这样写的
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); z.show1(); z.show2(); } } /** * 父类 * * @author LGL * */ class Fu { void show1() { System.out.println("fu"); } } /** * 子类 * * @author LGL * */ class Zi extends Fu { void show2() { System.out.println("zi"); } }
这是很正常的实现
我们当然要说一种特殊情况,子父类方法同名我们该怎么办?我们运行一下
这是子运行了,这种情况叫做覆盖(重写),这个特性的特点
- 当子类出现和父类一模一样的函数时,当子类对象被调用了该函数,会运行子类函数的内容,如同父类的函数被覆盖一样,这种情况就是覆盖了
当子类继承了父类,沿袭了父类的功能到子类中,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义并重写功能内容
覆盖
1.子类覆盖父类,必须保证子类权限大于等于父类权限才可以覆盖,否则编译失败
2.静态只能覆盖静态(一般没人用)记住
重载:只看同名函数的参数列表
重写:字符类方法要一模一样 ,包括返回值类型
3.构造函数
最后一个特点了
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); } } /** * 父类 * * @author LGL * */ class Fu { public Fu() { System.out.println("fu"); } } /** * 子类 * * @author LGL * */ class Zi extends Fu { public Zi() { System.out.println("zi"); } }
我们现在运行一下
你会疑问,我明明实例化的是子类,怎么父类也实例化了,因为子类构造函数的第一行默认有一个方法
super();
在对子类对象进行初始化时,父类的构造函数也会执行,那就是因为子类的构造函数默认第一行有一条隐式的语句super();他会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()
为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所有子类建立对象的时候,需要先查看父类如何对这些数据进行初始化的,所有子类对这些对象初始化时,要先访问父类中的构造函数,如果要访问父类中指定的构造函数,可以手动定义super(xx,xx)的方式。
注意
super语句一定定义在子类构造函数的第一行
结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数内的第一行都有一句隐式的super,当父类中没有空参数的构造函数时,子类必须手动通过super或者this语句的形式指定要访问父类中的构造函数
当然,子类的构造函数也可以指定this来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数,这个结论就是子类的实例化过程,逐级向上查找
父类也向上查找,他找的是JAVA中所有类的老爹——Object
行,我们本篇幅就闲到这里吧,概念多了,反而难以消化,我们要一点点的来
如果有兴趣可以加群:555974449,这可能是迄今为止最和谐的IT群了
-
JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖...
2018-04-03 07:01:59JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖 一.单例设计模式 什么是设计模式? JAVA当中有23种设计模式,解决某一问题最有效的方法 单例设计模式 解决一个类在内存中...JAVA之旅(六)——单例设计模式,继承extends,聚集关系,子父类变量关系,super,覆盖
一.单例设计模式
- 什么是设计模式?
JAVA当中有23种设计模式,解决某一问题最有效的方法
- 单例设计模式
解决一个类在内存中只存在一个对象
想要保证对象唯一该怎么做》
- 1.为了避免其他程序过多建立该类对象,先禁止其他程序建立该类对象
- 2.还为了让其他程序访问到该类对象,只好在本类中自定义一个对象
- 3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式
这三步怎么怎么实现呢?
- 1.将构造函数私有化
- 2.在类中创建一个本类对象
- 3.提供一个方法可以获取到该对象
然后我们的代码就出来了
/** * 单例模式 * * @author LGL * */ public class Single { // 将构造函数私有化 private Single() { } // 在类中创建一个本类对象 private static Single s = new Single(); // 提供一个方法可以获取到该对象 public static Single getInstance() { return s; } }
当然,我们还有一种写法——懒汉式
/** * 单例模式 * 懒汉式 * @author LGL * */ public class Single { private static Single s = null; public Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { if (s == null) s = new Single(); return s; } }
也有这么一种写法
/** * 单例模式 * 饿汉式 * * @author LGL * */ public class Single { private static Single s = new Single(); public Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { return s; } }
单例模式的写法多种多样,只要掌握这个思想就可以了
饿汉式的特点:single类一进内存就已经创建好了对象
懒汉式的特点:对象是方法被调用时才初始化,也叫作对象的延迟加载Single类进内存还没有存在,只有调用了getInstance()方法时才建立对象,这就叫做延迟加载
我们一般用饿汉式,因为他安全,简单
二.继承
面向对象的思想中的一个思想,继承,我们可以这样去理解,我们可以定义一个学生类,他有名字和年龄,还有一个学习的方法
/** * 学生 * @author LGL * */ class Student { String name; int age; void study() { System.out.println("学习"); } }
然后我们可以再定义一个工人类
/** * 工人 * @author LGL * */ class Worker { String name; int age; void work() { System.out.println("工作"); } }
他同样有名字和年龄还有一个工作的方法
这个时候我们可以发现,他们都存在相同的关系,他们都是人,人都具备年龄和姓名,所以我们可以将学生和工人的共性提取出来描述,只要让学生和工人与单独描述的类有关系就行,也就是继承
/** * 人 * * @author LGL * */ class Person { String name; int age; }
这个Person就叫做父类,超类,基类
然后我们的工人和学生就可以这样去写
/** * 学生 * * @author LGL * */ class Student extends Person { void study() { System.out.println("学习"); } } /** * 工人 * * @author LGL * */ class Worker extends Person { void work() { System.out.println("工作"); } }
他们是Person的子类,继承是源于生活,所以工人不能继承学生,没有伦理性,千万不要为了获取其他类的功能,简化代码而继承,必须是类与类之间有所属关系才可以继承,is a 的关系
继承的优点- 1.提高代码的复用性
- 2.让类与类之间产生关系,有了这层关系才有了多态的特性
JAVA语言中,java只支持单继承,不支持多继承
- 为什么不能多继承?
因为多继承容易带来安全隐患,当多个父类中定义了相同的功能,当功能内容不同时,子类对象不确定运行哪一个,但是JAVA保留了这种机制,并用另一种体现形式来表示,多实现。
JAVA支持多层继承,也就是一个继承体系
如何使用一个继承体系的功能?
- 想要使用体系,先查阅体系中父类的描述,因为父类中定义的是该体系中的共性内容,通过了解共性功能就可以知道该体系的基本功能,那么,这么体系已经可以基本使用了。
- 那么集体调用时,要创建最子类的对象,为什么?一是因为有可能父类不能创建对象,二是创建子类对象可能使用更多的功能,包括基本的也包括特有的
简单的说一句:查阅父类功能,创建子类对象使用功能
三.聚集关系
这个概念可能很多人不是很熟悉,确实我们实际开发当中很少提到,我们对象和对象之间,不光有继承关系,还有组合关系,
- 聚合
球员是球队中的一个,球队中有球员,这就是聚合关系
- 组合
手是人身体的一部分,腿是身体的一部分,这就是组合关系,你说这和聚合没什么不同,那你就错了,要知道,球队少了个球员没事,人少胳膊少腿就有事哦,所以组合关系更加紧密一点
都是吧对象撮合在一起,像我们继承是秉承一个is a的关系,而聚集是has a的关系,谁里面有谁
这个关系我们就不多做赘述了
我们关系讲完了,现在应该可以用代码去表示表示了,这里我就用当继承关系时,子类和父类之间的变量关系来举例
四.子父类变量关系
我们来探索一下子父类出现后,类成员的特点
-
- 变量
- 2.函数
- 3.构造函数
我们一步步来分析
1.变量
我们撸一串代码
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); System.out.println("num1 = " + z.num1 + "\n" + "num2 = " + z.num2); } } /** * 父类 * * @author LGL * */ class Fu { int num1 = 4; } /** * 子类 * * @author LGL * */ class Zi extends Fu { int num2 = 5; }
这样,是不是很容易知道输出的结果
但是我们那会这么简单,我们还有特殊情况
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); System.out.println("num1 = " + z.num + "\n" + "num2 = " + z.num); } } /** * 父类 * * @author LGL * */ class Fu { int num = 4; } /** * 子类 * * @author LGL * */ class Zi extends Fu { int num = 5; }
当子类和父类都有相同的变量的时候,现在该打印什么呢?
没错,打印了子类的值,为什么?因为输出的num前面其实默认带了一个this,如果我们要打印父类的值,需要加super,这是一个新的关键字了
void show(){ System.out.println(super.num); }
结果显而易见了
所以变量的特点:如果子类中出现非私有的同名成员变量时,子类要访问本类中的成员变量,用this,子类访问父类中的同名变量,用super,this和super的使用几乎一致,this代表的是本类对象的引用,super代表父类对象的引用
不过我们也不会这么蛋疼在父类创建又在子类创建,我们来看第二个
2.函数
也就是方法,我们正常的应该是这样写的
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); z.show1(); z.show2(); } } /** * 父类 * * @author LGL * */ class Fu { void show1() { System.out.println("fu"); } } /** * 子类 * * @author LGL * */ class Zi extends Fu { void show2() { System.out.println("zi"); } }
这是很正常的实现
我们当然要说一种特殊情况,子父类方法同名我们该怎么办?我们运行一下
这是子运行了,这种情况叫做覆盖(重写),这个特性的特点
- 当子类出现和父类一模一样的函数时,当子类对象被调用了该函数,会运行子类函数的内容,如同父类的函数被覆盖一样,这种情况就是覆盖了
当子类继承了父类,沿袭了父类的功能到子类中,到子类中,但是子类虽具备该功能,但是功能的内容却和父类不一致,这时没有必要定义新功能,而是使用覆盖特性,保留父类的功能定义并重写功能内容
- 覆盖
1.子类覆盖父类,必须保证子类权限大于等于父类权限才可以覆盖,否则编译失败
2.静态只能覆盖静态(一般没人用) - 记住
重载:只看同名函数的参数列表
重写:字符类方法要一模一样 ,包括返回值类型
3.构造函数
最后一个特点了
//公共的 类 类名 public class HelloJJAVA { // 公共的 静态 无返回值 main方法 数组 public static void main(String[] str) { /** * 子父类出现后,类成员的特点 */ Zi z = new Zi(); } } /** * 父类 * * @author LGL * */ class Fu { public Fu() { System.out.println("fu"); } } /** * 子类 * * @author LGL * */ class Zi extends Fu { public Zi() { System.out.println("zi"); } }
我们现在运行一下
你会疑问,我明明实例化的是子类,怎么父类也实例化了,因为子类构造函数的第一行默认有一个方法
super();
- 1
在对子类对象进行初始化时,父类的构造函数也会执行,那就是因为子类的构造函数默认第一行有一条隐式的语句super();他会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()
- 为什么子类一定要访问父类中的构造函数?
因为父类中的数据子类可以直接获取,所有子类建立对象的时候,需要先查看父类如何对这些数据进行初始化的,所有子类对这些对象初始化时,要先访问父类中的构造函数,如果要访问父类中指定的构造函数,可以手动定义super(xx,xx)的方式。
- 注意
super语句一定定义在子类构造函数的第一行
- 结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数,因为子类每一个构造函数内的第一行都有一句隐式的super,当父类中没有空参数的构造函数时,子类必须手动通过super或者this语句的形式指定要访问父类中的构造函数
当然,子类的构造函数也可以指定this来访问本类中的构造函数,子类中至少会有一个构造函数会访问父类中的构造函数,这个结论就是子类的实例化过程,逐级向上查找
父类也向上查找,他找的是JAVA中所有类的老爹——Object
行,我们本篇幅就闲到这里吧,概念多了,反而难以消化,我们要一点点的来
- 什么是设计模式?
-
电子商务跟CRM是什么关系?.docx
2020-06-10 02:48:19电子商务跟CRM是什么关系 电子商务通常是指是在全球各地广泛的商业贸易活动中在因特网开放的网络环境下基于浏览器/服务器应用方式买卖双方不谋面地进行各种商贸活动实现消费者的网上购物商户之间的网上交易和在线... -
8-电子商务跟CRM是什么关系?.pdf
2020-03-03 18:15:02电子商务跟CRM 是什么关系 电子商务通常是指是在全球各地广泛的商业贸易活动中在因特网开放的网络环境下基于浏览器/服务器应 用方式买卖双方不谋面地进行各种商贸活动实现消费者的网上购物商户之间的网上交易和在线... -
ems数字货币运营模式,emstoken是什么,emstoken骗局揭秘
2019-01-25 14:22:111.三位一体,交易所,币子,APP都是公司的,目前没有一个锁仓币能做到这一点,很多锁仓模式又不长久就是因为app和发行方没有关系。 2.公司没压力,公司每天奖励的币子数量而不是现金,会员到交易大盘挂卖或者对冲...【ems数字货币官网】韩国 emstoken是什么, emstoken数字货币怎么样?
【ems数字货币官网】韩国 emstoken是什么?真的是传销骗局吗?
1.三位一体,交易所,币子,APP都是公司的,目前没有一个锁仓币能做到这一点,很多锁仓模式又不长久就是因为app和发行方没有关系。
2.公司没压力,公司每天奖励的币子数量而不是现金,会员到交易大盘挂卖或者对冲才能变现,而且变现的速度非常快,每天奖励的数量是有限的不够每天报单的,一币难求!很多锁仓模式走不长跑路是因为app和发行方没关系,需要自己在平台买币奖励给会员这样和拿现金没什么区别,一旦币子价格上涨就更受不了,而EMS不是,它奖励会员的币子是交易所的平台币,自己发行,每天奖励会员的不是现金是币子。
3.锁仓周期,总共发行5个亿,市场流通3000万,4.2亿公司拿出来赠送,5000万公司自己留用。静态加动态的奖励一天最多也就100多万币,有100人如果报单一万币锁仓就没有了。把这4.2个亿送完得一年多。所以现在正是好时机因为刚刚开始!
4.复投增加粘性,静态加动态三倍出局增加了平台的粘性,因为不复投动态和静态的奖励都没有,所以没有会看着钱不赚,肯定都会复投激活,这样大家都复投就会让现金流更加稳定。
5.老板的发心,老板发行币子无非是想把数字变成资产。公司留的5000万币子如果价格拉升到10元一个就是5个亿,如果拉升到100就是50个亿,这种锁仓模式买的人多卖的人少,价格会平稳上涨,只要价格涨到一定的程度老板把手里自留的币子分批量投向市场,那么就达到了预期的目的。这样币子都会在会员手中持有互相买卖。价格不断上涨会吸引更多交易里的散户购买持有,所以最后锁仓的会员和老板手中的币子的利润都来源于市场,达到双赢。
6.天天见钱,变现快,不需要对冲。直推奖天天拿
7.EMS有真正应用场景,在菲律宾赌场都可以直接兑换筹码。持币十万公司给办万事达卡全球通用银联提款机直接可以提现。不久的将来在很多购物平台可以消费真正的当现金使用。
我对区块链钱包有长时间的研究,模式制度究竟好与不好,选择哪个项目好,都是有专业度的,所以期待您的探讨和交流! -
你觉得外观模式和代理模式的联系和区别是什么?_切图仔最后的倔强:包教不包会设计模式...
2020-11-25 22:43:451. 什么是结构型模式结构型模式主要用于处理类和对象的组合,对应思维导图:2. 外观模式: Facade Pattern对接口二次封装隐藏其复杂性,并简化其使用。外观模式包含如下角色:Facade: 外观角色SubSystem: 子系统角色...1. 什么是结构型模式
结构型模式主要用于处理类和对象的组合,对应思维导图:
2. 外观模式: Facade Pattern
对接口二次封装隐藏其复杂性,并简化其使用。
外观模式包含如下角色:Facade
: 外观角色SubSystem
: 子系统角色
使用时机
当我们将系统分成多个子系统时,我们会降低代码复杂性。编程时的最佳实践是最小化子系统之间的通信和依赖关系。实现这一目标的一个好方法是引入一个
facade
对象,为子系统提供单一且统一的接口。1. 跨浏览器监听事件
要保证处理事件的代码在大多数浏览器下一致运行,需要关注冒泡阶段。
在做跨浏览器网站时,你已经不经意间使用了外观模式:
var addMyEvent = function( el,ev,fn ){
if( el.addEventListener ){//存在DOM2级方法,则使用并传入事件类型、事件处理程序函数和第3个参数false(表示冒泡阶段)
el.addEventListener( ev,fn, false );
}else if(el.attachEvent){ // 为兼容IE8及更早浏览器,注意事件类型必须加上"on"前缀
el.attachEvent( "on" + ev, fn );
}else{
el["on" + ev] = fn;//其他方法都无效,默认采用DOM0级方法,使用方括号语法将属性名指定为事件处理程序
}
};2. jQuery $(document).ready(..)
我们都熟悉
$(document).ready(..)
。在源码中,这实际上是一个被调用的方法提供的bindReady()
:加载事件共用两种方法
:window.onload()
和$(document).ready()
bindReady: function() {
...
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );
// If IE event model is used
} else if ( document.attachEvent ) {
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );Facade
外观模式大量应用于jQuery
库以让其更容易被使用。譬如我们使用jQuery
的$(el).css()
或$(el).animate()
等方法 。使我们不必手动在
jQuery
内核中调用很多内部方法以便实现某些行为,也同时避免了手动与DOM API
交互。类似的还有
D3.js
3. 适配器模式: Adapter Pattern
传统:适配两个及以上类接口不兼容的问题
JS
: 可额外适配两个及以上代码库、前后端数据等。
使用时机
通常使用适配器的情况:需要集成新组件并与应用程序中的现有组件一起工作。
重构,程序的哪些部分用改进的接口重写,但旧代码仍然需要原始接口。
1. jQuery.fn.css()规范化显示
// Cross browser opacity:
// opacity: 0.9; Chrome 4+, FF2+, Saf3.1+, Opera 9+, IE9, iOS 3.2+, Android 2.1+
// filter: alpha(opacity=90); IE6-IE8
// Setting opacity
$( ".container" ).css( { opacity: .5 } );
// Getting opacity
var currentOpacity = $( ".container" ).css('opacity');内部实现为:
get: function( elem, computed ) {
return ropacity.test( (
computed && elem.currentStyle ?
elem.currentStyle.filter : elem.style.filter) || "" ) ?
( parseFloat( RegExp.$1 ) / 100 ) + "" :
computed ? "1" : "";
},
set: function( elem, value ) {
var style = elem.style,
currentStyle = elem.currentStyle,
opacity = jQuery.isNumeric( value ) ?
"alpha(opacity=" + value * 100 + ")" : "",
filter = currentStyle && currentStyle.filter || style.filter || "";
style.zoom = 1;
// 如果将不透明度设置为1,则移除其他過濾器
//exist - attempt to remove filter attribute #6652
if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
style.removeAttribute( "filter" );
if ( currentStyle && !currentStyle.filter ) {
return;
}
}
// otherwise, set new filter values
style.filter = ralpha.test( filter ) ?
filter.replace( ralpha, opacity ) :
filter + " " + opacity;
}
};2. Vue中的computed
yck - 《前端面试之道》
在
Vue
中,我们其实经常使用到适配器模式。比如父组件传递给子组件一个时间戳属性,组件内部需要将时间戳转为正常的日期显示,一般会使用
computed
来做转换这件事情,这个过程就使用到了适配器模式。4. 代理模式: Proxy Pattern
为其他对象提供一种代理以便控制对这个对象的访问。
可以详细控制访问某个类(对象)的方法,在调用这个方法前作的前置处理(统一的流程代码放到代理中处理)。调用这个方法后做后置处理。
例如:明星的经纪人,租房的中介等等都是代理
使用代理模式的意义是什么?
“单一职责原则”:面向对象设计中鼓励将不同的职责分布到细粒度的对象中,Proxy 在原对象的基础上进行了功能的衍生而又不影响原对象,符合松耦合高内聚的设计理念
遵循“开放-封闭原则”:代理可以随时从程序中去掉,而不用对其他部分的代码进行修改,在实际场景中,随着版本的迭代可能会有多种原因不再需要代理,那么就可以容易的将代理对象换成原对象的调用。
特点:
解决系统之间的耦合度以及系统资源开销大
通过代理对象可保护被代理的对象,使其扩展性不受外界的影响
在js中,它的执行常常依托于浏览器
事件代理就用到了代理模式。
分类:
远程代理(
Remote Proxy
):为一个位于不同的地址空间的对象提供一个本地的代理对象虚拟代理(
Virtual Proxy
):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。保护代理(
Protect Proxy
):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。缓冲代理(
Cache Proxy
):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。智能引用代理(
Smart Reference Proxy
):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。
缺点::
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。
实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂,例如远程代理。
前端用得最多的是 虚拟代理、保护代理、缓冲代理
1. ES6中的Proxy
ES6
所提供Proxy
构造函数能够让我们轻松的使用代理模式:// target: 表示所要代理的对象,handler: 用来设置对所代理的对象的行为。
let proxy = new Proxy(target, handler);2. 图片预加载
目前一般的网站都会有图片预加载机制,也就是在真正的图片在被加载完成之前用一张菊花图(转圈的gif图片)表示正在加载图片。
const img = new Image();
img.src = '/some/big/size/image.jpg';
document.body.appendChild(img);创建虚拟图片节点
virtualImg
并构造创建代理函数:// 图片懒加载: 虚拟代理
const createImgProxy = (img, loadingImg, realImg) => {
let hasLoaded = false;
const virtualImg = new Image();
virtualImg.src = realImg;
virtualImg.onload = () => {
Reflect.set(img, 'src', realImg);
hasLoaded = true;
}
return new Proxy(img, {
get(obj, prop) {
if (prop === 'src' && !hasLoaded) {
return loadingImg;
}
return obj[prop];
}
});最后是将原始的图片节点替换为代理图片进行调用:
const img = new Image();
const imgProxy = createImgProxy(img, '/loading.gif', '/some/big/size/img.jpg');
document.body.appendChild(imgProxy);3. 分页数据:缓存代理
如,前后端分离,向后端请求分页的数据的时候,每次页码改变时都需要重新请求后端数据,我们可以将页面和对应的结果进行缓存,当请求同一页的时候,就不再请求后端的接口而是从缓存中去取数据。
const getFib = (number) => {
if (number <= 2) {
return 1;
} else {
return getFib(number - 1) + getFib(number - 2);
}
}
const getCacheProxy = (fn, cache = new Map()) => {
return new Proxy(fn, {
apply(target, context, args) {
const argsString = args.join(' ');
if (cache.has(argsString)) {
// 如果有缓存,直接返回缓存数据 console.log(`输出${args}的缓存结果: ${cache.get(argsString)}`);
return cache.get(argsString);
}
const result = fn(...args);
cache.set(argsString, result);
return result;
}
})
}
const getFibProxy = getCacheProxy(getFib);
getFibProxy(40); // 102334155getFibProxy(40); // 输出40的缓存结果: 1023341554. 事件代理
事件代理就用到了代理模式。
<ul id="ul">
<li>1li>
<li>2li>
<li>3li>
<li>4li>
<li>5li>
ul>
<script>let ul = document.querySelector('#ul')
ul.addEventListener('click', (event) => {console.log(event.target);
})script>通过给父节点绑定一个事件,让父节点作为代理去拿到真实点击的节点。
5. 装饰者模式: Decorator Pattern
在不改变原对象的基础上,通过对其进行包装拓展(添加属性或者方法)使原有对象可以满足用户更复杂的需求
装饰器类似于高阶函数的概念。装饰器将基本形式作为参数,并在其上添加处理并将其返回。
优点:优点是把类(函数)的核心职责和装饰功能区分开了。
问题:
装饰链叠加了函数作用域,如果过长也会产生性能问题。
在
JavaScript
中:装饰者模式提供比继承更有弹性的替代方案。
装饰者用于包装同接口的对象,用于通过重载方法的形式添加新功能,该模式可以在被装饰者的前面或后面加上自己的行为以达到特定的目的。
核心就是缓存上一次的函数
1. 简单例子
举一个简单的例子:
var xiaoming = function () {
this.run = function () {
return '跑步'
},
this.eat = function () {
return: '吃饭'
}
}
// 小明可以跑步,也可以吃饭
// 下面是一个装饰类,给小明进行装饰
var decor = function (xiaoming) {
this.run = function () {
return xiaoming.run + '很快'
}
this.eat = function () {
return xiaoming.eat + '很多'
}
}通过一个装饰类,实现了对小明类的装饰。
2. TypeScript 函数修饰符: @
“@”,与其说是修饰函数倒不如说是引用、调用它修饰的函数。
或者用句大白话描述:@: "下面的被我包围了。"
举个栗子,下面的一段代码,里面两个函数,没有被调用,也会有输出结果:
test(f){
console.log("before ...");
f()
console.log("after ...");
}
@test
func(){
console.log("func was called");
}直接运行,输出结果:
before ...
func was called
after ...3. React 中的装饰器模式
在
React
中,装饰器模式随处可见:import React, { Component } from 'react';
import {connect} from 'react-redux';
class App extends Component {
render() {
//...
}
}
// const mapStateToProps
// const actionCreators
export default connect(mapStateToProps,actionCreators)(App);Ant Design
中创建表单的最后一步其实也算装饰器模式class CustomizedForm extends React.Component {}
CustomizedForm = Form.create({})(CustomizedForm);6. 桥接模式:Bridge Pattern
桥接模式将实现层与抽象次层解耦分离,使两部分可以独立变化。该模式包含如下角色:
Abstraction
(抽象类)RefinedAbstraction
(扩充抽象类)Implementor
(实现类接口)ConcreteImplementor
(具体实现类)
常用于应用程序(客户端)和数据库驱动程序(服务):
应用程序写入定义的数据库API,例如
ODBC
,但在此API之后,会发现每个驱动程序的实现对于每个数据库供应商(SQL Server,MySQL,Oracle
等)都是完全不同的。多见于驱动程序开发,在
JavaScript
中很少见。一些软件的跨平台设计有时候也是应用了桥接模式
1. 网站主题替换
在大型网站中,不同模块可能会有不同主题,也有分白天/黑夜 或 用户自主选择的主题。
这时为每个主题创建每个页面的多个副本明显不合理,而桥接模式是更好的选择:
javascript-design-patterns-for-human
不同模块:
class About{
constructor(theme) {
this.theme = theme
}
getContent() {
return "About page in " + this.theme.getColor()
}
}
class Careers{
constructor(theme) {
this.theme = theme
}
getContent() {
return "Careers page in " + this.theme.getColor()
}
}以及不同主题:
class DarkTheme{
getColor() {
return 'Dark Black'
}
}
class LightTheme{
getColor() {
return 'Off white'
}
}
class AquaTheme{
getColor() {
return 'Light blue'
}
}生成主题:
const darkTheme = new DarkTheme()
const about = new About(darkTheme)
const careers = new Careers(darkTheme)
console.log(about.getContent() )// "About page in Dark Black"
console.log(careers.getContent() )// "Careers page in Dark Black"7. 组合模式: Composite Pattern
又称 部分-整体模式,将对象组合成树形结构以表示“部分整体”的层次结构。
使得用户对单个对象和组合对象的使用具有一致性。(参考卡片和表单组成)
该模式包含以下角色:
Component
- 声明组合中对象的接口并实现默认行为(基于Composite
)Leaf
- 表示合成中的原始对象Composite
- 在Component
接口中实现与子相关的操作,并存储Leaf(primitive)
对象。
1. 操作系统中的文件目录结构
计算机文件结构是组合模式的一个实例。
如果你删除某个文件夹,也将删除该文件夹的所有内容,是吗?这实质上就是组合模式运行原理。你
你可以调用结构树上较高层次的组合对象,消息将沿这一层次结构向下传输。
2. 批量操作DOM
Javascript设计模式理论与实战:组合模式
HTML
文档的DOM
结构就是天生的树形结构,最基本的元素醉成DOM树,最终形成DOM
文档,非常适用适用组合模式。我们常用的
jQuery
类库,其中组合模式的应用更是频繁,例如经常有下列代码实现:$(".test").addClass("noTest").removeClass("test");
不论$
(“.test”)
是一个元素,还是多个元素,最终都是通过统一的addClass
和removeClass
接口进行调用。我们简单模拟一下
addClass
的实现:var addClass = function (eles, className) {
if (eles instanceof NodeList) {
for (var i = 0, length = eles.length; i eles[i].nodeType === 1 && (eles[i].className += (' ' + className + ' '));
}
}
else if (eles instanceof Node) {
eles.nodeType === 1 && (eles.className += (' ' + className + ' '));
}
else {
throw "eles is not a html node";
}
}
addClass(document.getElementById("div3"), "test");
addClass(document.querySelectorAll(".div"), "test");对于
NodeList
或者是Node
来说,客户端调用都是同样的使用了addClass
这个接口,这个就是组合模式的最基本的思想,使部分和整体的使用具有一致性。8. 享元模式:Flyweight Pattern
享元(
flyweight
)模式是一种用于性能优化的模式,“fly
”在这里是苍蝇的意思,意为蝇量级。主要用于减少创建对象的数量,以减少内存占用和提高性能
运用共享技术来有效支持大量细粒度的对象
享元模式的核心是运用共享技术来有效支持大量细粒度的对象。
如果系统中因为创建了大量类似的对象而导致内存占用过高,享元模式就非常有用了。在
JavaScript
中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一件非常有意义的事情。享元模式有以下角色:
客户端:用来调用享元工厂来获取内在数据的类,通常是应用程序所需的对象,
享元工厂:用来维护享元数据的类
享元类:保持内在数据的类
1. 简单例子
在下面的例子中,我们创建了一个“Book”类来处理有关特定书籍,然后创建一个“
BookFactory
”类来控制如何创建这些Book对象。为了获得更好的内存性能,如果同一对象被实例化两次,则会重用这些对象。
class Book {
constructor(title, isbn, author, ratings) {
this.title = title;
this.isbn = isbn;
this.author = author;
this.ratings = ratings;
}
getAverageReview() {
let averageReview = (this.ratings.reduce((a,b) => a+b)) / this.ratings.length
return averageReview;
}
}
class BookFactory {
constructor() {
this._books = [];
}
createBook(title, isbn, author, ratings) {
let book = this.getBookBy(isbn);
if (book) { //重用对象
return book;
} else {
const newBook = new Book(title, isbn, author, ratings);
this._books.push(newBook);
return newBook;
}
}
getBookBy(attr) {
return this._books.find(book => book.attr === attr);
}
}2. 在线表格思路实现
打开谷歌在线表格,提取打印其节点元素。
可以看到就算是滚动至千行,它们都只是共用两个视图。
用的就是享元模式,来防止无限滚动造成卡顿。
以下是模拟实现:
首先是HTML
<section id="app">
<table id="table">table>
<div class="controls">
<input type="range" name="scroll" id="scroll" value="0">
div>
section>样式:
#app {
position: relative;
padding: 30px 0 30px 10px;
#table {
padding: 20px;
border-radius: 10px;
min-width: 450px;
transition: background 0.5s;
background: rgba(73, 224, 56, 0.1);
&.low-range {
background: rgba(73, 224, 56, 0.47);
td {
border-bottom: 1px solid rgba(73, 224, 56, 0.9)
}
}
&.mid-range {
background: rgba(224, 196, 56, 0.47);
td {
border-bottom: 1px solid rgba(224, 196, 56, 0.9)
}
}
&.high-range {
background: rgba(224, 56, 56, 0.47);
td {
border-bottom: 1px solid rgba(224, 56, 56, 0.9)
}
}
&.ultra-high-range {
background: rgba(224, 56, 56, 0.9);
td {
border-bottom: 1px solid black
}
}
td {
border-bottom: 1px solid black;
padding: 10px;
font-weight: bold;
}
}
.controls {
padding-top: 20px;
#scroll {
width: 450px;
box-sizing: border-box;
}
}
}逻辑实现,请配合注释食用:
// 生成单元格实例
const makeRowCells = data => data.map(value => new Cell(value));
// 定义常量
const scrollViewport = 10; // 当前表格视图大小
const tableSize = 2000; // 行数
let scrollIndex = 0; // 初始滚动索引
let DATA = []; // 初始数据集
while (DATA.length const unit = DATA.length * 10;
DATA.push('12345678'.split('').map(() => unit));
}
/**
* cell类 - 列
*/
class Cell {
constructor(content) {
this.content = content;
}
// 更新列
updateContent(content) {
this.content = content;
this.cell.innerText = content;
}
// 渲染列
render() {
const cell = document.createElement('td');
this.cell = cell;
cell.innerText = this.content;
return cell;
}
}
/**
* row类 - 行
*/
class Row {
constructor(cellItems) {
this.cellItems = cellItems;
}
// 更新行
updateRowData(newData) {
this.cellItems.forEach((item, idx) => {
item.updateContent(newData[idx]);
});
}
// 渲染行
render() {
const row = document.createElement('tr');
this.cellItems.forEach(item => row.appendChild(item.render()));
return row;
}
}
/**
* 表格类
*/
class Table {
constructor(selector) {
this.$table = document.querySelector(selector);
}
// 添加行
addRows(rows) {
this.rows = rows;
this.rows.forEach(row => this.$table.appendChild(row.render()));
}
// 更新table数据
updateTableData(data) {
this.rows.forEach((row, idx) => row.updateRowData(data[idx]));
}
}
// 实例化新表
const table = new Table('#table');
// 匹配滚动条的DOM
const scrollControl = document.querySelector('#scroll');
// 在table下添加单元格行
table.addRows(
DATA.map(dataItem => new Row(makeRowCells(dataItem))));
const onScrollChange = event => {
// 为视图准备新数据
DATA = DATA.map((item, idx) => item.map(cell => parseInt(event.target.value, 10)*10 + idx*10));
// 更新当前table的数据
table.updateTableData(DATA);
// 添加颜色区别样式
scrollIndex = event.target.value;
if (event.target.value >= 0) {
table.$table.classList = 'low-range';
}
if (event.target.value > tableSize * 0.4) {
table.$table.classList = 'mid-range';
}
if (event.target.value > tableSize * 0.7) {
table.$table.classList = 'high-range';
}
if (event.target.value > tableSize * 0.9) {
table.$table.classList = 'ultra-high-range';
}
};
// 设置滚动条最小和最大范围
scrollControl.setAttribute('min', 0);
scrollControl.setAttribute('max', tableSize);
// 添加滚动事件
scrollControl.addEventListener('input', onScrollChange);
// 初始化事件
const event = {target: {value: 0}};
onScrollChange(event);9. 结语及参考
至此,结构型设计模式已经讲(水)完了,其中享元模式值得单独拿出来写一篇博客。
-
什么是软件架构?什么是设计模式?它能起到什么作用?
2005-03-26 21:34:00一、什么是软件架构?软件是由模块,类等单元组成,这些单元组成更大的包,子系统. 软件架构就是将整个系统分析为一个逻辑的包,子系统,层,并制定他们之间的逻辑关系,物理分布关系. 架构很多,比如说j2ee就是... -
数据库系统概论 第七章 数据库设计(3)扩展E-R...向关系模型的转换,联系,设计用户子模式,数据模型的优化
2020-06-27 13:50:19有的实体型是某个实体型的子类型,这种父类0子类的联系称为ISA联系,表示is a语义,用????表示 ISA联系的性质,子类继承了父类的所有属性,子类也可以有自己的属性。 (1)分类属性 分类属性是父实体型的一个属性 ... -
mysql 简单模式_初探mysql数据库模式(一)
2021-02-02 00:07:07数据库模式是什么?数据库模式是描述整个数据库的数据结构和数据库底层架构的事务。它分为逻辑模式(俗称:“模式”),外模式(俗称:“子模式”or“用户模式”),内模式(俗称:...数据库关系模式是什么?它所指待的是... -
为什么要学习设计模式?
2017-10-04 10:41:37设计面向对象软件比较困难,而设计...有经验的面向对象设计者会告诉你,要一下子就得到复用性和灵活性好的设计,即使不是不可能的至少也是非常困难的。一个设计在最终完成之前常要被复用好几次,而且每一次都有所修改。 -
设计模式:组合模式
2019-07-30 23:55:34索引什么是组合模式组合模式必须知道的角色组合模式实现的关键部分组合模式工作流程分析模拟杀毒软件架构设计 什么是组合模式 组合模式就是把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理... -
设计模式之装饰器模式
2019-05-16 11:38:07装饰器模式动态来扩展对象的功能,是继承关系的一个替代方案。 二.为什么需要装饰器模式 通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生子类来扩展,抑或是使用对象组合的方式。显然,直接修改... -
设计模式之组合模式
2021-01-28 10:35:00一、什么是组合模式 组合模式(Composite),将对象组合成树形结构以表示“部分-整体”的层次结构,用户对单个对象和组合对象的使用具有一致性。 所以当我们的案例是树形结构或者是部分-整体的关系时,就可以... -
【设计模式】Java设计模式之外观模式
2020-02-15 19:33:55目录 一、为什么要使用外观模式 二、模式定义 三、模式结构 四、模式优点 五、模式缺点 ...一、为什么要使用外观模式 ...引入外观角色之后,用户只需要直接与外观角色交互,用户与子系统之间的复杂关系由... -
php后端模式,php-fpm以及php-cgi, fast-cgi,以及与nginx的关系
2018-10-26 11:43:00关于cgi是什么,fast-cgi是什么,php-cgi是什么,fast-cgi是什么,下面这篇讲的很清楚: https://segmentfault.com/q/1010000000256516 另外,nginx本身不处理php请求,它是把请求发fastcgi管理进程处理,fascgi... -
JAVA设计模式之外观模式
2017-11-10 11:04:241. 什么是外观模式? 《Head First设计模式》中定义,提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,使子系统更容易使用。 外观模式可以让客户和子系统之间避免紧密耦合,避开... -
代理模式
2019-09-30 13:56:25代理模式,就是AOP的编程,类似于...外观模式是屏蔽使用端和子系统间的业务逻辑关系,使他们解除耦合。更好地重用、和维护。 使用需求例子: 公司里只有一部打印机,大家都可以用、但是有一天你的老板说公司的打印... -
java设计模式之装饰模式
2019-06-11 11:58:37一 什么是装饰模式 装饰器模式 装饰器模式又称为包装(Wrapper)模式。装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加... -
什么是分布式?什么是集群?
2018-06-30 16:28:55简单说,分布式是以缩短单个任务的... 采用分布式方案,提供10台服务器,每台服务器只负责处理一个子任务,不考虑子任务间的依赖关系,执行完这个任务只需一个小时。(这种工作模式的一个典型代表就是Hadoop的Map/R... -
组合模式_程序员必备技能:设计模式之——组合模式
2021-01-12 16:08:09什么是组合模式“组合模式”也被称为“部分整体模式”该模式属于结构型模式的一种。讲解该模式之前先带大家熟悉一下“树形结构”。相信大家对“树形结构”不会太陌生,如果你刚好不太了解的话可以想一下大树,一颗树... -
iOS_设计模式学习:外观模式
2018-08-11 02:17:56一、外观模式是什么 外观模式为子系统中一组不同的接口提供统一的接口。 外观定义了上层接口,通过降低复杂度和隐藏子系统间的通信及依存关系,让子系统更易于使用。 类图如下: 二、外观模... -
23种模式中的外观模式
2019-10-02 02:25:431.什么是外观模式? 外观模式定义了一个将子系统的一组接口集成在一起的高层接口,以提供一个一致的界面。通过这个界面,其他系统可以方便的调用子系统的功能,而忽略子系统内部的变化。 2.使用的场合 1.为... -
23中设计模式之门面模式
2016-09-20 11:33:581.什么是门面模式 2.门面结构类图 3.门面模式使用场景先说门面模式属于结构型模式中设计模式,主要解决对象组成和对象之间的依赖关系。门面模式:外部与子系统进行通信必须通过一个统一的门面(Facade)对象进行,... -
什么是分布式
2017-05-27 10:37:00222013-10简单说,分布式是以缩短单个...采用分布式方案,提供10台服务器,每台服务器只负责处理一个子任务,不考虑子任务间的依赖关系,执行完这个任务只需一个小时。(这种工作模式的一个典型代表就是Hadoop的Map... -
读书笔记_软件架构与设计模式_第3章软件设计的模式
2020-10-12 17:56:40设计模式的目标是什么? b. 设计模式是如何形成的? c. 什么是微架构? d. 包含很多设计模式的架构就是好架构吗? Answer: 三者的抽象程度依次降低。架构关注的是系统的架构,系统模式通常是在子系统中解决特定...
-
物联网基础篇:快速玩转MQTT
-
MySQL 备份与恢复详解(高低版本 迁移;不同字符集 相互转换;表
-
java spring创建事物_Spring事务管理的方式_JavaEE框架(Maven+SpringMvc+Spring+MyBatis)全程实战教程_Java视频-51CTO学院...
-
java spring上传文件_Spring实现文件的上传下载
-
java spring 登录验证_springmvc-spring-mybatis实现最简单的登录验证
-
linux基础入门和项目实战部署系列课程
-
java spring 数据校验_Spring 数据校验
-
java springmvc 上传后台_SpringMVC上传图片代码实例
-
NFS 网络文件系统
-
Mycat 实现 MySQL的分库分表、读写分离、主从切换
-
Mysql数据库面试直通车
-
LVS + Keepalived 实现 MySQL 负载均衡与高可用
-
基于电商业务的全链路数据中台落地方案(全渠道、全环节、全流程)
-
OnePlusToolBox:用于运行OxygenOSHydrogenOS 11的OnePlus的工具箱-源码
-
java springmvc 上传后台_微信小程序上传图片到服务器(java后台以及使用springmvc)...
-
项目管理工具与方法
-
SPFD5408A PVI 2.6 inch Application Note_20070706.pdf
-
华为1+X——网络系统建设与运维(高级)
-
java spring上传文件到服务器_springboot实现上传图片到服务器,前端及java后台代码总结...
-
零基础一小时极简以太坊智能合约开发环境搭建并开发部署