Skip to content

Commit cb2a6fa

Browse files
committed
Added another example of proxy pattern. Announcer from JMock demos by Nat Pryce.
1 parent eb75773 commit cb2a6fa

File tree

17 files changed

+316
-21
lines changed

17 files changed

+316
-21
lines changed

proxy/etc/proxy.png

12.5 KB
Loading

proxy/etc/proxy.ucls

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,59 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
3-
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
4-
<class id="1" language="java" name="com.iluwatar.proxy.WizardTowerProxy" project="proxy"
5-
file="/proxy/src/main/java/com/iluwatar/proxy/WizardTowerProxy.java" binary="false" corner="BOTTOM_RIGHT">
6-
<position height="142" width="214" x="260" y="438"/>
2+
<class-diagram version="1.1.10" icons="true" automaticImage="PNG" always-add-relationships="false"
3+
generalizations="true" realizations="true" associations="true" dependencies="false" nesting-relationships="true"
4+
router="FAN">
5+
<class id="1" language="java" name="com.iluwatar.proxy.example1.WizardTowerProxy" project="proxy"
6+
file="/proxy/src/main/java/com/iluwatar/proxy/example1/WizardTowerProxy.java" binary="false" corner="BOTTOM_RIGHT">
7+
<position height="-1" width="-1" x="407" y="454"/>
78
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
89
sort-features="false" accessors="true" visibility="true">
910
<attributes public="true" package="true" protected="true" private="true" static="true"/>
1011
<operations public="true" package="true" protected="true" private="true" static="true"/>
1112
</display>
1213
</class>
13-
<class id="2" language="java" name="com.iluwatar.proxy.Wizard" project="proxy"
14-
file="/proxy/src/main/java/com/iluwatar/proxy/Wizard.java" binary="false" corner="BOTTOM_RIGHT">
15-
<position height="124" width="117" x="187" y="274"/>
14+
<class id="2" language="java" name="com.iluwatar.proxy.example1.Wizard" project="proxy"
15+
file="/proxy/src/main/java/com/iluwatar/proxy/example1/Wizard.java" binary="false" corner="BOTTOM_RIGHT">
16+
<position height="-1" width="-1" x="684" y="455"/>
1617
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
1718
sort-features="false" accessors="true" visibility="true">
1819
<attributes public="true" package="true" protected="true" private="true" static="true"/>
1920
<operations public="true" package="true" protected="true" private="true" static="true"/>
2021
</display>
2122
</class>
22-
<class id="3" language="java" name="com.iluwatar.proxy.WizardTower" project="proxy"
23-
file="/proxy/src/main/java/com/iluwatar/proxy/WizardTower.java" binary="false" corner="BOTTOM_RIGHT">
24-
<position height="106" width="130" x="344" y="274"/>
23+
<class id="3" language="java" name="com.iluwatar.proxy.example1.WizardTower" project="proxy"
24+
file="/proxy/src/main/java/com/iluwatar/proxy/example1/WizardTower.java" binary="false" corner="BOTTOM_RIGHT">
25+
<position height="-1" width="-1" x="408" y="217"/>
2526
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
2627
sort-features="false" accessors="true" visibility="true">
2728
<attributes public="true" package="true" protected="true" private="true" static="true"/>
2829
<operations public="true" package="true" protected="true" private="true" static="true"/>
2930
</display>
3031
</class>
31-
<generalization id="4">
32+
<class id="4" language="java" name="com.iluwatar.proxy.example1.App" project="proxy"
33+
file="/proxy/src/main/java/com/iluwatar/proxy/example1/App.java" binary="false" corner="BOTTOM_RIGHT">
34+
<position height="-1" width="-1" x="141" y="455"/>
35+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
36+
sort-features="false" accessors="true" visibility="true">
37+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
38+
<operations public="true" package="true" protected="true" private="true" static="true"/>
39+
</display>
40+
</class>
41+
<dependency id="5">
42+
<end type="SOURCE" refId="4"/>
43+
<end type="TARGET" refId="1"/>
44+
</dependency>
45+
<dependency id="6">
46+
<end type="SOURCE" refId="3"/>
47+
<end type="TARGET" refId="2"/>
48+
</dependency>
49+
<generalization id="7">
3250
<end type="SOURCE" refId="1"/>
3351
<end type="TARGET" refId="3"/>
3452
</generalization>
53+
<dependency id="8">
54+
<end type="SOURCE" refId="1"/>
55+
<end type="TARGET" refId="2"/>
56+
</dependency>
3557
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
3658
sort-features="false" accessors="true" visibility="true">
3759
<attributes public="true" package="true" protected="true" private="true" static="true"/>

proxy/src/main/java/com/iluwatar/proxy/App.java renamed to proxy/src/main/java/com/iluwatar/proxy/example1/App.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
* THE SOFTWARE.
2222
*/
23-
package com.iluwatar.proxy;
23+
package com.iluwatar.proxy.example1;
2424

2525
/**
2626
*

proxy/src/main/java/com/iluwatar/proxy/Wizard.java renamed to proxy/src/main/java/com/iluwatar/proxy/example1/Wizard.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
* THE SOFTWARE.
2222
*/
23-
package com.iluwatar.proxy;
23+
package com.iluwatar.proxy.example1;
2424

2525
/**
2626
*

proxy/src/main/java/com/iluwatar/proxy/WizardTower.java renamed to proxy/src/main/java/com/iluwatar/proxy/example1/WizardTower.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
* THE SOFTWARE.
2222
*/
23-
package com.iluwatar.proxy;
23+
package com.iluwatar.proxy.example1;
2424

2525
/**
2626
*

proxy/src/main/java/com/iluwatar/proxy/WizardTowerProxy.java renamed to proxy/src/main/java/com/iluwatar/proxy/example1/WizardTowerProxy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
* THE SOFTWARE.
2222
*/
23-
package com.iluwatar.proxy;
23+
package com.iluwatar.proxy.example1;
2424

2525
/**
2626
*
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.iluwatar.proxy.example2;
2+
3+
import java.lang.reflect.InvocationTargetException;
4+
import java.lang.reflect.Method;
5+
import java.lang.reflect.Proxy;
6+
import java.util.List;
7+
import java.util.concurrent.CopyOnWriteArrayList;
8+
9+
public class Announcer {
10+
11+
private HealthMonitor proxy;
12+
private List<HealthMonitor> listeners = new CopyOnWriteArrayList<>();
13+
14+
public Announcer(Class<HealthMonitor> listenerType) {
15+
proxy = createProxy(listenerType);
16+
}
17+
18+
private HealthMonitor createProxy(Class<HealthMonitor> listenerType) {
19+
return listenerType.cast(Proxy.newProxyInstance(listenerType.getClassLoader(),
20+
new Class<?>[] {listenerType}, (proxy, method, args) -> {
21+
invokeAll(method, args);
22+
return null;
23+
}));
24+
}
25+
26+
private void invokeAll(Method method, Object[] args) {
27+
for (HealthMonitor listener : listeners) {
28+
try {
29+
method.invoke(listener, args);
30+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
31+
e.printStackTrace();
32+
}
33+
}
34+
}
35+
36+
public void registerListener(HealthMonitor listener) {
37+
listeners.add(listener);
38+
}
39+
40+
public HealthMonitor announce() {
41+
return proxy;
42+
}
43+
44+
public void removeListener(HealthMonitor listener) {
45+
listeners.remove(listener);
46+
}
47+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package com.iluwatar.proxy.example2;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.Map.Entry;
6+
7+
/**
8+
* An application representing a health monitoring system. Endpoints such as TCP connections, UDP
9+
* connections, DB connections keep fluctuating and may get disconnected. To monitor the health of
10+
* these endpoints user can attach health monitors to the endpoint and when the status of the
11+
* connectivity changes the health monitors are notified of the changes.
12+
*
13+
* The class that implements the Proxy pattern is {@link Announcer}.
14+
*
15+
* @see Announcer
16+
*
17+
* @author npathai
18+
*
19+
*/
20+
public class App {
21+
22+
public static void main(String[] args) {
23+
24+
EndPoint endPoint = new EndPoint("TCP Endpoint");
25+
ConsoleMonitor consoleMonitor = new ConsoleMonitor();
26+
HealthCounter counter = new HealthCounter();
27+
endPoint.addMonitor(consoleMonitor);
28+
endPoint.addMonitor(counter);
29+
30+
endPoint.connected();
31+
endPoint.disconnect();
32+
endPoint.connected();
33+
endPoint.disconnect();
34+
endPoint.connected();
35+
36+
counter.printCounters();
37+
}
38+
39+
private static class ConsoleMonitor implements HealthMonitor {
40+
41+
@Override
42+
public void disconnected(EndPoint endPoint) {
43+
System.out.println(endPoint + " is disconnected.");
44+
}
45+
46+
@Override
47+
public void connected(EndPoint endPoint) {
48+
System.out.println(endPoint + " is connected");
49+
}
50+
}
51+
52+
private static class HealthCounter implements HealthMonitor {
53+
private Map<String, Health> endPointNameToHealth = new HashMap<>();
54+
55+
private class Health {
56+
private boolean connected;
57+
private int disconnectedCount = 0;
58+
private int connectedCount = 0;
59+
}
60+
61+
@Override
62+
public void disconnected(EndPoint endPoint) {
63+
Health health = endPointNameToHealth.get(endPoint.getName());
64+
if (health == null) {
65+
health = new Health();
66+
endPointNameToHealth.put(endPoint.getName(), health);
67+
}
68+
health.connected = false;
69+
health.disconnectedCount++;
70+
}
71+
72+
@Override
73+
public void connected(EndPoint endPoint) {
74+
Health health = endPointNameToHealth.get(endPoint.getName());
75+
if (health == null) {
76+
health = new Health();
77+
endPointNameToHealth.put(endPoint.getName(), health);
78+
}
79+
health.connected = true;
80+
health.connectedCount++;
81+
}
82+
83+
public void printCounters() {
84+
for (Entry<String, Health> entry : endPointNameToHealth.entrySet()) {
85+
System.out.println(String.format("EndPoint: %s, Connected: %s, Connected Count: %d, Disconnected Count: %d",
86+
entry.getKey(), entry.getValue().connected, entry.getValue().connectedCount,
87+
entry.getValue().disconnectedCount));
88+
}
89+
}
90+
}
91+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.iluwatar.proxy.example2;
2+
3+
public class EndPoint {
4+
5+
private final String name;
6+
private final Announcer healthMonitors = new Announcer(HealthMonitor.class);
7+
8+
public EndPoint(String name) {
9+
this.name = name;
10+
}
11+
12+
public void addMonitor(HealthMonitor monitor) {
13+
healthMonitors.registerListener(monitor);
14+
}
15+
16+
public void disconnect() {
17+
healthMonitors.announce().disconnected(this);
18+
}
19+
20+
public void connected() {
21+
healthMonitors.announce().connected(this);
22+
}
23+
24+
public String getName() {
25+
return name;
26+
}
27+
28+
@Override
29+
public String toString() {
30+
return name;
31+
}
32+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.iluwatar.proxy.example2;
2+
3+
public interface HealthMonitor {
4+
5+
void disconnected(EndPoint endPoint);
6+
7+
void connected(EndPoint endPoint);
8+
9+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy