Skip to content

Commit

Permalink
strategy decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
Debri committed Jun 21, 2017
1 parent d6398cb commit 0bdf597
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 48 deletions.
54 changes: 46 additions & 8 deletions SQL语句执行过程.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,49 @@
### 当Server端收到了Client发送的SQL语句以后
1. 查询高速缓存,如果存在相同的执行计划,则会直接执行这个SQL省区后面的工作
1. 首先对SQL语句进行语法解析,
1. 进行语义解析
1. 获得对象的解析锁
1. 数据访问权限的核对
1. 确定执行计划
1. 执行语句
1. 提取结果
1.
* 从内存中读取数据要比从硬盘中的数据文件中读取数据效率要高
* 另外一方面省去了解析SQL语句
1. 首先对SQL语句进行语法解析,服务器进程就会开始检查这条语句的合法性。这里主要是对 SQL 语句的语法进行检查,看看其是否合乎语法规则。
1. 进行语义解析,服务器进程接下去会对语句中的字段、表等内容进行检查。看看这些字段、表是否在数据库中。
* 如果表名与列名不准确的话,则数据库会就会反馈错误信息给客户端。
1. 获得对象的解析锁,系统就会对我们需要查询的对象加锁。
* 这主要是为了保障数据的一致性,防止我们在查询的过程中,其他用户对这个对象发生改变。
1. 数据访问权限的核对,服务器进程还会检查,你所连接的用户是否有这个数据访问的权限。若你连接上服务器的用户不具有数据访问权限的话,则客户端就不能够取得这些数据。
* 数据库服务器进程**先检查语法与语义,然后才会检查访问权限**
1. 确定最佳执行计划。服务器进程会根据一定的规则,对这条语句进行优化
* 不过要注意,这个优化是有限的。
* 一般在应用软件开发的过程中,需要对数据库的 sql 语言进行优化,这个优化的作用要大大地大于服务器进程的自我优化。
* 当服务器进程的优化器**确定这条查询语句的最佳执行计划后,就会将这条 SQL 语句与执行计划保存到数据高速缓存(library cache)**。如此的话,等以后还有这个查询时,就会省略以上的语法、语义与权限检查的步骤,
而直接执行 SQL 语句,提高 SQL 语句处理效率。
1. 执行语句。执行语句也分成两种情况
* 一是若被选择行所在的数据块已经被读取到数据缓冲区的话,则服务器进程会直接把这个数据传递给客户端,而不是从数据库文件中去查询数据。
* 若数据不在缓冲区中,则服务器进程将从数据库文件中查询相关数据,并把这些数据放入到数据缓冲区中(buffer cache)。

1. 提取结果。当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程,所以,在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询动作。从这整个查询处理过程中,我们在数据库开发或者应用软件开发过
程中,需要注意以下几点:
* 一是要了解数据库缓存跟应用软件缓存是两码事情。数据库缓存只有在数据库服务器端才存在,在
客户端是不存在的。只有如此,才能够保证数据库缓存中的内容跟数据库文件的内容一致。才能够根据
相关的规则,防止数据脏读、错读的发生。而应用软件所涉及的数据缓存,由于跟数据库缓存不是一码事
情,所以,应用软件的数据缓存虽然可以提高数据的查询效率,但是,却打破了数据一致性的要求,有时候
会发生脏读、错读等情况的发生。所以,有时候,在应用软件上有专门一个功能,用来在必要的时候清除
数据缓存。不过,这个数据缓存的清除,也只是清除本机上的数据缓存,或者说,只是清除这个应用程序
的数据缓存,而不会清除数据库的数据缓存。
* 二是绝大部分 SQL 语句都是按照这个处理过程处理的。我们 DBA 或者基于 Oracle 数据库的
开发人员了解这些语句的处理过程,对于我们进行涉及到 SQL 语句的开发与调试,是非常有帮助的。有
时候,掌握这些处理原则,可以减少我们排错的时间。特别要注意,数据库是把数据查询权限的审查放在
语法语义的后面进行检查的。所以,有时会若光用数据库的权限控制原则,可能还不能满足应用软件权限
控制的需要。此时,就需要应用软件的前台设置,实现权限管理的要求。而且,有时应用数据库的权限管
理,也有点显得繁琐,会增加服务器处理的工作量。因此,对于记录、字段等的查询权限控制,大部分程
序涉及人员喜欢在应用程序中实现,而不是在数据库上实现。

---

### SQL语句中的函数、关键字、排序等执行顺序:
1. FROM 子句返回初始结果集。
2. WHERE 子句排除不满足搜索条件的行。
3. GROUP BY 子句将选定的行收集到 GROUP BY 子句中各个唯一值的组中。
4. 选择列表中指定的聚合函数可以计算各组的汇总值。
5. 此外,HAVING 子句排除不满足搜索条件的行。
6. 计算所有的表达式;
7. 使用 order by 对结果集进行排序。
8. 查找你要搜索的字段。
Binary file added image/1345385564_5334.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/Strategy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 0 additions & 36 deletions 排序/快速排序.md.bak

This file was deleted.

82 changes: 82 additions & 0 deletions 设计模式/策略模式.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
## 策略模式(StrategyPattern)
### 概述
> 策略模式(Strategy Pattern),将各种算法封装到具体的类中,作为一个抽象策略类的子类,使得它们可以互换。客户端可以自行决定使用哪种算法。
### 结构图和说明
结构图如下图所示
![image]( )
1. Strategy 策略接口或者(抽象策略类),定义策略执行接口
2. ConcreteStrategy 具体策略类
3. Context 上下文类,持有具体策略类的实例,并负责调用相关的算法
### 代码实现
(1)抽象策略类

public interface Strategy {
public void operation(String input);
}

(2)具体策略类

public class ConcreteStrategyA implements Strategy {
@Override
public void operation(String input) {
//do something
System.out.println("ConcreteStrategyA do something : " + input);
}
}

(3)策略上下文,负责调用具体的策略

public class SimpleContext {
private Strategy strategy;

public SimpleContext(Strategy strategy) {
this.strategy = strategy;
}

public void action(String input) {
strategy.operation(input);
}
}

(4)客户端,调用策略模式

public class Client {
public static void main(String[] args) {
Strategy strategy = new ConcreteStrategyA();
SimpleContext context = new SimpleContext(strategy);
context.action("hello world");
}
}


 从上面的示例可以看出,策略模式仅仅封装算法,提供新的算法插入到已有系统中,以及老算法从系统中“退休”的方法,策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。


### 小结
  **策略模式的重心**

  策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

  **算法的平等性**

  策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。

  所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。

  **运行时策略的唯一性**

  运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。

  **公有的行为**

  经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。
#### 优点
1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。

2. 使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

#### 缺点
1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

2. 由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
86 changes: 86 additions & 0 deletions 设计模式/装饰器模式.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## 装饰器模式(DecoratorPattern)
### 概念
> 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。在面向对象的设计中,而我们也应该尽量使用对象组合,而不是对象继承来扩展和复用功能。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。装饰器模式的本质就是动态组合。动态是手段,组合才是目的。总之,装饰模式是通过把复杂的功能简单化,分散化,然后再运行期间,根据需要来动态组合的这样一个模式
### 模式结构说明

装饰模式的结构如下图所示

![image](./2011110423171991.jpg)
Component(原始类):组件对象的接口,可以给这些对象动态的添加职责;

ConcreteComponent(继承类):具体的组件对象,实现了组件接口。该对象通常就是被装饰器装饰的原始对象,可以给这个对象添加职责;

Decorator(装饰器基类):所有装饰器的父类,需要定义一个与组件接口一致的接口(主要是为了实现装饰器功能的复用,即具体的装饰器A可以装饰另外一个具体的装饰器B,因为装饰器类也是一个Component),并持有一个Component对象,该对象其实就是被装饰的对象。如果不继承组件接口类,则只能为某个组件添加单一的功能,即装饰器对象不能在装饰其他的装饰器对象。

ConcreteDecorator(装饰器实现类):具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象。

### 代码实现(in java)
(1)组件对象的接口,可以给这些对象动态添加职责
```
public interface Component {
public void operation();
}
```
(2)具体实现组件对象接口的对象
```
public class ConcreateComponent implements Component {
@Override
public void operation() {
//do something
}
}
```
(3)装饰器接口,维持一个指向组件对象的接口对象, 并定义一个与组件接口一致的接口
```
public abstract class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
//转发请求给组件对象,可以在转发之后执行一些附加动作
component.operation();
}
}
```
装饰器的具体实现对象,向组件对象添加职责,operationFirst(),operationLast()为前后需要添加的功能。具体的装饰器类ConcreteDecoratorB代码相似
```
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
private void operationFirst() {
//在调用父类的operation方法之前需要执行的操作
}
private void operationLast() {
//在调用父类的operation方法之后需要执行的操作
}
public void operation() {
//调用父类的方法,可以在调用前后执行一些附加动作
operationFirst(); //添加的功能
super.operation(); //这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,实现了新的功能
operationLast(); //添加的功能
}
}
```
(5)客户端使用装饰器
```
public class Client {
public static void main(String[] args) {
Component component = new ConcreateComponent();
Decorator myDecorator = new ConcreteDecoratorA(new ConcreteDecoratorB(component));
myDecorator.operation();
}
}
```
### 总结
Java中的IO是明显的装饰器模式的运用。FilterInputStream,FilterOutputStream,FilterRead,FilterWriter分别为具体装饰器的父类,相当于Decorator类,它们分别实现了InputStream,OutputStream,Reader,Writer类(这些类相当于Component,是其他组件类的父类,也是Decorator类的父类)。继承自InputStream,OutputStream,Reader,Writer这四个类的其他类是具体的组件类,每个都有相应的功能,相当于ConcreteComponent类。而继承自FilterInputStream,FilterOutputStream,FilterRead,FilterWriter这四个类的其他类就是具体的装饰器对象类,即ConcreteDecorator类。通过这些装饰器类,可以给我们提供更加具体的有用的功能。如FileInputStream是InputStream的一个子类,从文件中读取数据流,BufferedInputStream是继承自FilterInputStream的具体的装饰器类,该类提供一个内存的缓冲区类保存输入流中的数据。我们使用如下的代码来使用BufferedInputStream装饰FileInputStream,就可以提供一个内存缓冲区来保存从文件中读取的输入流。
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); //其中file为某个具体文件的File或者FileDescription对象
#### 在以下两种情况下可以考虑使用装饰器模式:
(1)需要在不影响其他对象的情况下,以动态、透明的方式给对象添加职责。

(2)如果不适合使用子类来进行扩展的时候,可以考虑使用装饰器模式。
4 changes: 0 additions & 4 deletions 设计模式/观察者模式.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@
### 使用场景

一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用。

一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变,也不知道这些对象是谁。

需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。





### MVC软件框架模型

MVC(Model-View-Controller)架构中也应用了观察者模式,MVC是一种架构模式,它包含三个角色:模型(Model),视图(View)和控制器(Controller)。其中模型可对应于观察者模式中的观察目标,而视图对应于观察者,控制器可充当两者之间的中介者。当模型层的数据发生改变时,视图层将自动改变其显示内容
Expand Down

0 comments on commit 0bdf597

Please sign in to comment.