官术网_书友最值得收藏!

The Observer design pattern

Another similarity that the keen reader may have noticed is with the Observer design pattern. It is mainly used in object-oriented applications as a way for objects to communicate with each other without having any knowledge of who depends on its changes.

In Clojure, a simple version of the Observer pattern can be implemented using watches:

(def numbers (atom [])) 
 
(defn adder [key ref old-state new-state] 
  (print "Current sum is " (reduce + new-state))) 
 
(add-watch numbers :adder adder) 

We will start by creating our program state, which in this case is an atom holding an empty vector. Next, we will create a watch function that knows how to sum all numbers in numbers. Finally, we will add our watch function to the numbers atom under the :adder key (useful for removing watches).

The adder key conforms with the API contract required by add-watch and receives four arguments. In this example, we only care about new-state.

Now, whenever we update the value of numbers, its watch will be executed, as demonstrated in the following code:

(swap! numbers conj 1) 
;; Current sum is  1 
 
(swap! numbers conj 2) 
;; Current sum is  3 
 
(swap! numbers conj 7) 
;; Current sum is  10 

The highlighted lines indicate the result that is printed on the screen each time we update the atom.

Though useful, the Observer pattern still requires some amount of work in setting up the dependencies and the required program state, in addition to being hard to compose.

That being said, this pattern has been extended and is at the core of one of the Reactive Programming frameworks we will look at later in this book, Microsoft's Reactive Extensions (Rx).

主站蜘蛛池模板: 新巴尔虎左旗| 赣榆县| 武城县| 凤台县| 鸡泽县| 石狮市| 栾城县| 玛曲县| 将乐县| 建昌县| 扶风县| 江门市| 徐汇区| 万山特区| 乌拉特前旗| 云南省| 绥化市| 织金县| 兴和县| 大余县| 当阳市| 大姚县| 东台市| 福州市| 祁阳县| 玛沁县| 油尖旺区| 邵阳市| 托克逊县| 南城县| 依兰县| 潢川县| 石棉县| 大方县| 襄樊市| 科技| 北辰区| 普陀区| 罗城| 陵水| 惠东县|