auto commit
This commit is contained in:
parent
c7b0547206
commit
8ff530f158
|
@ -508,7 +508,13 @@ PizzaStore 由 orderPizza() 方法,顾客可以用它来下单。下单之后
|
|||
|
||||
<div align="center"> <img src="../pics//cfb05050-47aa-4fd1-86eb-a7c86320f81b.png"/> </div><br>
|
||||
|
||||
**5. 代码实现**
|
||||
**5. 设计原则**
|
||||
|
||||
**依赖倒置原则** :要依赖抽象,不要依赖具体类。听起来像是针对接口编程,不针对实现编程,但是这个原则说明了:不能让高层组件依赖底层组件,而且,不管高层或底层组件,两者都应该依赖于抽象。例如,下图中 Pizza 是抽象类,PizzaStore 和 Pizza 子类都依赖于 Pizza 这个抽象类。
|
||||
|
||||
<div align="center"> <img src="../pics//ddf72ca9-c0be-49d7-ab81-57a99a974c8e.jpg"/> </div><br>
|
||||
|
||||
**6. 代码实现**
|
||||
|
||||
```java
|
||||
public interface Pizza {
|
||||
|
@ -606,27 +612,27 @@ ChicagoStyleCheesePizza is making..
|
|||
|
||||
## 3. 抽象工厂模式
|
||||
|
||||
**1. 设计原则**
|
||||
**1. 模式定义**
|
||||
|
||||
**依赖倒置原则** :要依赖抽象,不要依赖具体类。听起来像是针对接口编程,不针对实现编程,但是这个原则说明了:不能让高层组件依赖底层组件,而且,不管高层或底层组件,两者都应该依赖于抽象。例如,下图中 PizzaStore 属于高层组件,它依赖的是 Pizza 的抽象类,这样就可以不用关心 Pizza 的具体实现细节。
|
||||
提供一个接口,用于创建 **相关对象家族** ,而不需要明确指定具体类。
|
||||
|
||||
<div align="center"> <img src="../pics//ddf72ca9-c0be-49d7-ab81-57a99a974c8e.jpg"/> </div><br>
|
||||
**2. 模式类图**
|
||||
|
||||
**2. 模式定义**
|
||||
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
|
||||
|
||||
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
|
||||
抽象工厂模式用到了工厂模式来创建单一对象,在类图左部,AbstractFactory 中的 CreateProductA 和 CreateProductB 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂模式的定义。
|
||||
|
||||
**3. 模式类图**
|
||||
至于创建对象的家族这一概念是在 Client 体现,Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象,在这里这两个对象就有很大的相关性,Client 需要这两个对象的协作才能完成任务。
|
||||
|
||||
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂模式只是用于创建一个对象,这和抽象工厂模式有很大不同。并且,抽象工厂模式也用到了工厂模式来创建单一对象,在类图左部,AbstractFactory 中的 CreateProductA 和 CreateProductB 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂模式的定义。至于创建对象的家族这一概念是在 Client 体现,Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象,在这里这两个对象就有很大的相关性,Client 需要这两个对象的协作才能完成任务。从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory ,而工厂模式使用了继承。
|
||||
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory ,而工厂模式使用了继承。
|
||||
|
||||
<div align="center"> <img src="../pics//d301774f-e0d2-41f3-95f4-bfe39859b52e.jpg"/> </div><br>
|
||||
<div align="center"> <img src="../pics//0de18cdb-e974-47a3-af47-9538edafe857.png"/> </div><br>
|
||||
|
||||
**4. 解决方案类图**
|
||||
**3. 解决方案类图**
|
||||
|
||||
<div align="center"> <img src="../pics//8785dabd-1285-4bd0-b3aa-b05cc060a24a.jpg"/> </div><br>
|
||||
<div align="center"> <img src="../pics//967b2f5a-6ade-4ceb-bb41-493483fd3dff.png"/> </div><br>
|
||||
|
||||
**5. 代码实现**
|
||||
**4. 代码实现**
|
||||
|
||||
```java
|
||||
public interface Dough {
|
||||
|
@ -795,7 +801,7 @@ private static Singleton uniqueInstance = new Singleton();
|
|||
|
||||
因为 uniqueInstance 只需要被初始化一次,之后就可以直接使用了。加锁操作只需要对初始化那部分的代码进行,也就是说,只有当 uniqueInstance 没有被初始化时,才需要进行加锁。
|
||||
|
||||
双重校验锁先判断 uniqueInstance 是否已经被初始化了,如果没有被初始化,那么才对初始化的语句进行加锁。如果只做一次判断,那么多个线程还是有可能同时进入实例化语句块的,因此需要仅此第二次的判断。
|
||||
双重校验锁先判断 uniqueInstance 是否已经被初始化了,如果没有被初始化,那么才对初始化的语句进行加锁。
|
||||
|
||||
```java
|
||||
public class Singleton {
|
||||
|
@ -818,6 +824,16 @@ public class Singleton {
|
|||
}
|
||||
```
|
||||
|
||||
考虑下面的实现,也就是只使用了一个 if 语句。在 uniqueInstance == null 的情况下,如果两个线程同时执行 if 语句,那么两个线程就会同时进入 if 语句块内。虽然在 if 语句块内有加锁操作,但是两个线程都会执行 uniqueInstance = new Singleton(); 这条语句,只是早晚的问题,也就是说会进行两次实例化,从而产生了两个实例。
|
||||
|
||||
```java
|
||||
if (uniqueInstance == null) {
|
||||
synchronized (Singleton.class) {
|
||||
uniqueInstance = new Singleton();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# 命令模式
|
||||
|
||||
**1. 问题描述**
|
||||
|
|
BIN
pics/0de18cdb-e974-47a3-af47-9538edafe857.png
Normal file
BIN
pics/0de18cdb-e974-47a3-af47-9538edafe857.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 176 KiB |
BIN
pics/967b2f5a-6ade-4ceb-bb41-493483fd3dff.png
Normal file
BIN
pics/967b2f5a-6ade-4ceb-bb41-493483fd3dff.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 267 KiB |
Loading…
Reference in New Issue
Block a user