1 Definition in gof
Intention
Defines a one-to-many dependency between objects. When the status of an object changes, all objects dependent on it are notified and automatically updated. [Gof design patterns]
Structure chart
2. Overview
Personally, it is hard to understand the definition of the observer mode: when multiple observers focus on a topic, this mode solves the problem that an object needs to call a series of object methods, in addition, the caller registers whether he or she is called. The caller does not know which methods to call.
3 examples in life
Currently, there is one item in the banking business. When the account amount changes, the notification is sent to the mobile phone by default. You can also choose to send the information to the mailbox at the same time.
4. The caller depends on the called party
Scenario 1: at the beginning of the business, the account amount changes and the mobile phone number is notified.
Implementation:
View code
Public Class Account { Public Void Amountchange () {Phone = New Phone (); phone. Send ();}} Public Class Phone { Public Void Send () {console. writeline ( " Send phone! " );}} Static Void Main ( String [] ARGs) {account Account = New Account (); account. amountchange ();}
Note: Here, account is the caller (the so-called topic), and phone is the caller (the so-called observer ). Here, the caller is strongly dependent on the called party.
Scenario 2: When the business develops and the account amount changes, it notifies the mobile phone and the mailbox.
Implementation:
View code
Public Class Account { Public Void Amountchange () {Phone = New Phone (); email = New Email (); phone. Send (); email. Send ();}} Public Class Email { Public Void Send () {console. writeline ( " Send email! " );}} Public Class Phone { Public Void Send () {console. writeline ( " Send phone! " );}} Static Void Main ( String [] ARGs) {account Account = New Account (); account. amountchange ();}
Note: to add a new email sending function, you must modify the existing account class, which violates the open and closed principle.
5. The caller depends on the interface and the called party depends on the interface (according to the contract design)
Scenario 3: reconstruct scenario 2Code
Implementation:
View code
Public Class Account {ilist <Iobserver> olist = New List <iobserver> (); Public Void Attach (iobserver observer) {olist. Add (observer );} Public Void Amountchange (){ Foreach (Iobserver observer In Olist) {observer. sendpolicy ();}}} Public Interface Iobserver { Void Sendpolicy ();} Public Class Phone: iobserver { Public Void Sendpolicy () {console. writeline ( " Send phone! " );}} Public Class Email: iobserver { Public Void Sendpolicy () {console. writeline ( " Send email! " );}} Static Void Main ( String [] ARGs) {account Account = New Account (); email = New Email (); account. Attach (email); phone = New Phone (); account. Attach (phone); account. amountchange ();}
Note: here, the caller maintains a list of callers. To call the called caller, you only need to loop through this list. When a new observer is added, you only need to add a class that inherits the iobserver interface and then register the class on the client to the iobserver list;
6. Final reconstruction (Active grading)
Scenario 4: In scenario 3, the Operations registered by the caller to the call list are implemented in the Customer Code and passively registered by the caller, in the definition, whether or not the caller is called is determined by the caller rather than by the caller.
Implementation:
View code
Public Class Account {ilist <Iobserver> olist = New List <iobserver> (); Public Void Attach (iobserver observer) {olist. Add (observer );} Public Void Amountchange (){ Foreach (Iobserver observer In Olist) {observer. sendpolicy ();}}} Public Interface Iobserver { Void Sendpolicy ();} Public Class Phone: iobserver { Public Account subject; Public Phone (){} Public Phone (account subject ){ This . Subject = Subject; This . Subject. Attach ( This );} Public Void Sendpolicy () {console. writeline ( " Send phone! " );}} Public Class Email: iobserver { Public Account subject; Public Email (){} Public Email (account subject ){ This . Subject = Subject; This . Subject. Attach ( This );} Public Void Sendpolicy () {console. writeline ( " Send email! " );}} Static Void Main ( String [] ARGs) {account Account = New Account (); email = New Email (); phone = New Phone (account); account. amountchange (); Return ;}
Note: The caller determines whether the called party is called;
7. Summary
In general, the observer and command are very similar, all of which abstract the behavior and let the behavior change independently. However, the caller's decision on whether to call the called party is different. In command, the caller's decision is determined, and in observer, the caller's decision is determined. In the observer, if the called method is already implemented in a class, you can also integrate the adapter mode in the command mode to add a javaser class.