本文用来讲述设计模式中的依赖倒置原则。通过介绍,场景,代码推进的方式进行一步步的讲解。

一、介绍

依赖倒置原则(Dependence Inversion Principle)是指:

  1. 高层模块不应该依赖底层模块,二者都应该依赖其抽象。这里调用者就是上层,被调用者就是下层。
  2. 抽象不应该依赖细节,细节应该依赖抽象。(抽象是指接口或者抽象类,细节是指具体实现及使用)
  3. 依赖倒置的中心思想是面向接口编程
  4. 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在 java 中,抽象指的是接口或抽象类,细节就是具体的实现类
  5. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成
  6. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

本章用来讲述设计模式中的另一个原则——组合优于继承原则,又称为合成复用原则。

一、基本介绍

该原则是尽量使用合成/聚合的方式,而不是使用继承。

上面一句话就是对该原则的核心,但单单看这么一句话还是显得过于枯燥与不知所云,下面我们还是结合具体的场景进行代码推进,对该原则进行讲解。

二、场景

假设我们需要设计这样一个集合,每次向里面加入元素时,count都加一。例如:

最初集合是空集合,此时我们向里面加入"a",此时集合为{"a"},那么此时count = 1;当加入"b","c"两个元素时,集合为{"a","b","c"},此时count=3;此时再删除"a","c"两个元素,集合为{"b"},count仍然等于3;最后再加入"d",集合为{"b","d"}count=4

所以该场景是,不论中间是否删除元素,我们只统计加入到集合中的元素的次数,进行返回。

在对设计模式的学习中,首先需要了解、掌握设计模式的七大原则,这样后续对设计模式的学习才能够更加的轻松与透彻。本章用于总结设计模式中的单一职责原则,该原则也是比较容易理解的。

一、基本介绍

对类来说的,即一个类应该只负责一项职责。如类 A 负责两个不同职责:职责 1,职责 2。当职责 1 需求变更而改变 A 时,可能造成职责 2 执行错误,所以需要将类 A 的粒度分解为 A1,A2。

二、场景应用

2.1 场景一

该场景模拟交通工具使用场景。

目的:模拟交通工具的运输形式。

反例代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class SingleExample {

public static void main(String[] args) {

Vehicle vehicle = new Vehicle();
vehicle.run("汽车");
vehicle.run("摩托车");
vehicle.run("飞机");
}
}

class Vehicle {
public void run(String vehicle) {
System.out.println(vehicle + "在公路上运行");
}
}

一、Nginx的安装

本次安装的环境为centos7.0的版本。

1.1 pcre依赖包的相关安装

  1. 安装pcre压缩包中的依赖

    1
    wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz
  2. 压缩包解压并进入解压后的文件夹

    1
    tar -zxvf pcre-8.37.tar.gz
  3. C++方面的依赖(openssl、zlib、gcc等依赖)

    因为Nginx依赖C++的编译环境,故需要安装C++方面的依赖。

    1
    yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
  4. ./configure

    作用:是用来检测你的安装平台的目标特征的。比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,一般用来生成 Makefile,为下一步的编译做准备

  5. make && make install

    进行编译与安装

这次在刷Leetcode时,在求解数组中的第K大问题时,想到了使用堆排序,因此本篇文章用于巩固对堆排序的学习以及代码实现。

题目描述:在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

输入:[3,2,3,1,2,4,5,5,6] 和 k = 4

输出:4

当时看到此题时,第一反应就是想到使用大顶堆来求解,在第K次调堆后,就能够得到最K大元素。后续以大顶堆进行为例。

先来简单回顾堆排序:堆是一棵完全二叉树。如果是一个大顶堆,则根节点递归的大于其左右孩子节点的值。

以大顶堆为例:(3,2,3,1,2,4,5,5,6),对该待排序列进行堆排序。

本文用来记录对并查集的学习与总结,并通过leetcode的两道题目来加深对其的理论与实战学习(实现代码Java)。学习一种数据结构,最高效的方式,就是学以致用,所以这里,以leetcode的题目为例。

给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:”a==b” 或 “a!=b”。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。

只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。

示例1:

输入:["a==b","b!=a"]
输出:false
解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。没有办法分配变量同时满足这两个方程。

示例2:

输入:["b==a","a==b"]
输出:true
解释:我们可以指定 a = 1 且 b = 1 以满足满足这两个方程。

本文用来简单记录JavaComparatorComparable接口特点与使用。

首先,分别查看官方对这两个接口的描述定义:

一、Comparator接口

This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

A comparison function, which imposes a total ordering on some collection of objects.

可以看出官方对该接口的描述是,它是一种比较函数,用于对一些集合中的对象进行总的排序。即:对集合中的元素进行排序。通过其源码可以看出,除了compare(T o1,T o2)方法,其他方法都给了默认实现。

1
int compare(T o1, T o2);

所以要想使用该接口,就得实现该接口的此方法。那么,该接口的作用是什么呢?

在之前的文章Servlet执行原理浅谈中对Servlet的整个原理做了大概介绍。我们知道客户端发送的请求是交给Servlet中的service方法进行处理。而在实际使用时,并没有直接重写service方法,而是继承了HttpServlet,重写了doGetdoPost等方法,而这期间又发生了什么呢。

首先,我们观察Servlet这个接口:

1
2
3
4
5
6
7
8
9
10
11
public interface Servlet {
void init(ServletConfig var1) throws ServletException;

ServletConfig getServletConfig();

void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

String getServletInfo();

void destroy();
}

Servlet是一个接口,其中包含5个方法,我们大多真正使用的是service方法,其他的几个方法并不常用。因此,就出现了以下两个实现类:

image-20201129170130519

在介绍Servlet之前,简单对web方面的知识做个小结。

一、Web知识小结

1.1 软件架构

这里的软件架构,指服务器软件工作的两种方式:

  1. C/S:客户端/服务器端
  2. B/S:浏览器/服务器端

1.2 网络通信三要素

  1. IP:电子设备(计算机)在网络中的唯一标识。作用:用于定位到具体的电子设备,这里指具体的一台计算机。
  2. port(端口):应用程序在计算机中的唯一标识,其范围在0~65536。作用:用于定位计算机中的具体应用程序(每个应用程序都在监听着具体的端口号)。
  3. 传输协议:规定了数据传输的规则(该如何发送数据,又该如何接受数据,最后该对接受到的数据如何解析)。
    1. 基础协议
      • tcp:安全协议,三次握手,速度稍慢。
      • udp:不安全协议,速度较快。

使用通用Mapper的目的是为了替我们生成常用增删改查操作的SQL语句,并能够简化对于Mybatis的操作。

一、快速入门

1.1 数据库表的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CREATE TABLE `tabple_emp` (
`emp_id` INT NOT NULL AUTO_INCREMENT,
`emp_name` VARCHAR ( 500 ) NULL,
`emp_salary` DOUBLE ( 15, 5 ) NULL,
`emp_age` INT NULL,
PRIMARY KEY ( `emp_id` )
);
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'tom', '1254.37', '27' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'jerry', '6635.42', '38' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'bob', '5560.11', '40' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'kate', '2209.11', '22' );
INSERT INTO `tabple_emp` ( `emp_name`, `emp_salary`, `emp_age` )
VALUES
( 'justin', '4203.15', '30' );