Skip to content

Commit 82d3d7b

Browse files
committed
Proxy pattern: Improve the example
1 parent 92f8501 commit 82d3d7b

File tree

12 files changed

+128
-89
lines changed

12 files changed

+128
-89
lines changed

proxy/README.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,24 @@ Surrogate
1818
Provide a surrogate or placeholder for another object to control
1919
access to it.
2020

21-
![alt text](./etc/proxy_1.png "Proxy")
21+
![alt text](./etc/proxy.png "Proxy")
2222

2323
## Applicability
2424
Proxy is applicable whenever there is a need for a more
2525
versatile or sophisticated reference to an object than a simple pointer. Here
2626
are several common situations in which the Proxy pattern is applicable
2727

28-
* a remote proxy provides a local representative for an object in a different address space.
29-
* a virtual proxy creates expensive objects on demand.
30-
* a protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights.
28+
* Remote proxy provides a local representative for an object in a different address space.
29+
* Virtual proxy creates expensive objects on demand.
30+
* Protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights.
3131

3232
## Typical Use Case
3333

34-
* control access to another object
35-
* lazy initialization
36-
* implement logging
37-
* facilitate network connection
38-
* to count references to an object
34+
* Control access to another object
35+
* Lazy initialization
36+
* Implement logging
37+
* Facilitate network connection
38+
* Count references to an object
3939

4040
## Real world examples
4141

proxy/etc/proxy.png

13.2 KB
Loading

proxy/etc/proxy.ucls

+39-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
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">
2+
<class-diagram version="1.1.11" icons="true" automaticImage="PNG" always-add-relationships="false"
3+
generalizations="true" realizations="true" associations="true" dependencies="false" nesting-relationships="true"
4+
router="FAN">
45
<class id="1" language="java" name="com.iluwatar.proxy.WizardTowerProxy" project="proxy"
56
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"/>
7+
<position height="149" width="191" x="388" y="271"/>
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"/>
@@ -12,26 +13,56 @@
1213
</class>
1314
<class id="2" language="java" name="com.iluwatar.proxy.Wizard" project="proxy"
1415
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"/>
16+
<position height="113" width="102" x="619" y="271"/>
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+
<interface id="3" language="java" name="com.iluwatar.proxy.WizardTower" project="proxy"
2324
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"/>
25+
<position height="77" width="116" x="388" y="460"/>
26+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
27+
sort-features="false" accessors="true" visibility="true">
28+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
29+
<operations public="true" package="true" protected="true" private="true" static="true"/>
30+
</display>
31+
</interface>
32+
<class id="4" language="java" name="com.iluwatar.proxy.IvoryTower" project="proxy"
33+
file="/proxy/src/main/java/com/iluwatar/proxy/IvoryTower.java" binary="false" corner="BOTTOM_RIGHT">
34+
<position height="113" width="116" x="761" y="271"/>
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+
<class id="5" language="java" name="com.iluwatar.proxy.App" project="proxy"
42+
file="/proxy/src/main/java/com/iluwatar/proxy/App.java" binary="false" corner="BOTTOM_RIGHT">
43+
<position height="95" width="114" x="917" y="271"/>
2544
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
2645
sort-features="false" accessors="true" visibility="true">
2746
<attributes public="true" package="true" protected="true" private="true" static="true"/>
2847
<operations public="true" package="true" protected="true" private="true" static="true"/>
2948
</display>
3049
</class>
31-
<generalization id="4">
50+
<association id="6">
51+
<end type="SOURCE" refId="1" navigable="false">
52+
<attribute id="7" name="tower"/>
53+
<multiplicity id="8" minimum="0" maximum="1"/>
54+
</end>
55+
<end type="TARGET" refId="3" navigable="true"/>
56+
<display labels="true" multiplicity="true"/>
57+
</association>
58+
<realization id="9">
59+
<end type="SOURCE" refId="4"/>
60+
<end type="TARGET" refId="3"/>
61+
</realization>
62+
<realization id="10">
3263
<end type="SOURCE" refId="1"/>
3364
<end type="TARGET" refId="3"/>
34-
</generalization>
65+
</realization>
3566
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
3667
sort-features="false" accessors="true" visibility="true">
3768
<attributes public="true" package="true" protected="true" private="true" static="true"/>

proxy/etc/proxy_1.png

-23 KB
Binary file not shown.

proxy/src/main/java/com/iluwatar/proxy/App.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* functionality to the object of interest without changing the object's code.
3636
* <p>
3737
* In this example the proxy ({@link WizardTowerProxy}) controls access to the actual object (
38-
* {@link WizardTower}).
38+
* {@link IvoryTower}).
3939
*
4040
*/
4141
public class App {
@@ -45,12 +45,12 @@ public class App {
4545
*/
4646
public static void main(String[] args) {
4747

48-
WizardTowerProxy tower = new WizardTowerProxy();
49-
tower.enter(new Wizard("Red wizard"));
50-
tower.enter(new Wizard("White wizard"));
51-
tower.enter(new Wizard("Black wizard"));
52-
tower.enter(new Wizard("Green wizard"));
53-
tower.enter(new Wizard("Brown wizard"));
48+
WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
49+
proxy.enter(new Wizard("Red wizard"));
50+
proxy.enter(new Wizard("White wizard"));
51+
proxy.enter(new Wizard("Black wizard"));
52+
proxy.enter(new Wizard("Green wizard"));
53+
proxy.enter(new Wizard("Brown wizard"));
5454

5555
}
5656
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
package com.iluwatar.proxy;
24+
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
/**
29+
*
30+
* The object to be proxyed.
31+
*
32+
*/
33+
public class IvoryTower implements WizardTower {
34+
35+
private static final Logger LOGGER = LoggerFactory.getLogger(IvoryTower.class);
36+
37+
public void enter(Wizard wizard) {
38+
LOGGER.info("{} enters the tower.", wizard);
39+
}
40+
41+
}

proxy/src/main/java/com/iluwatar/proxy/Wizard.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
*/
3030
public class Wizard {
3131

32-
private String name;
32+
private final String name;
3333

3434
public Wizard(String name) {
3535
this.name = name;
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,9 @@
1-
/**
2-
* The MIT License
3-
* Copyright (c) 2014 Ilkka Seppälä
4-
*
5-
* Permission is hereby granted, free of charge, to any person obtaining a copy
6-
* of this software and associated documentation files (the "Software"), to deal
7-
* in the Software without restriction, including without limitation the rights
8-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9-
* copies of the Software, and to permit persons to whom the Software is
10-
* furnished to do so, subject to the following conditions:
11-
*
12-
* The above copyright notice and this permission notice shall be included in
13-
* all copies or substantial portions of the Software.
14-
*
15-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21-
* THE SOFTWARE.
22-
*/
23-
package com.iluwatar.proxy;
24-
25-
import org.slf4j.Logger;
26-
import org.slf4j.LoggerFactory;
27-
28-
/**
29-
*
30-
* The object to be proxyed.
31-
*
32-
*/
33-
public class WizardTower {
34-
35-
private static final Logger LOGGER = LoggerFactory.getLogger(WizardTower.class);
36-
37-
public void enter(Wizard wizard) {
38-
LOGGER.info("{} enters the tower.", wizard);
39-
}
40-
41-
}
1+
package com.iluwatar.proxy;
2+
3+
/**
4+
* WizardTower interface
5+
*/
6+
public interface WizardTower {
7+
8+
void enter(Wizard wizard);
9+
}

proxy/src/main/java/com/iluwatar/proxy/WizardTowerProxy.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,27 @@
2727

2828
/**
2929
*
30-
* The proxy controlling access to the {@link WizardTower}.
30+
* The proxy controlling access to the {@link IvoryTower}.
3131
*
3232
*/
33-
public class WizardTowerProxy extends WizardTower {
33+
public class WizardTowerProxy implements WizardTower {
3434

3535
private static final Logger LOGGER = LoggerFactory.getLogger(WizardTowerProxy.class);
3636

3737
private static final int NUM_WIZARDS_ALLOWED = 3;
3838

3939
private int numWizards;
4040

41+
private final WizardTower tower;
42+
43+
public WizardTowerProxy(WizardTower tower) {
44+
this.tower = tower;
45+
}
46+
4147
@Override
4248
public void enter(Wizard wizard) {
4349
if (numWizards < NUM_WIZARDS_ALLOWED) {
44-
super.enter(wizard);
50+
tower.enter(wizard);
4551
numWizards++;
4652
} else {
4753
LOGGER.info("{} is not allowed to enter!", wizard);

proxy/src/test/java/com/iluwatar/proxy/WizardTowerTest.java renamed to proxy/src/test/java/com/iluwatar/proxy/IvoryTowerTest.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,21 @@
2727
import org.junit.Before;
2828
import org.junit.Test;
2929

30+
import java.util.Arrays;
31+
3032
import static org.junit.Assert.assertEquals;
3133
import static org.junit.Assert.assertTrue;
3234

3335
/**
34-
* Date: 12/28/15 - 9:18 PM
35-
*
36-
* @author Jeroen Meulemeester
36+
* Tests for {@link IvoryTower}
3737
*/
38-
public class WizardTowerTest {
38+
public class IvoryTowerTest {
3939

4040
private InMemoryAppender appender;
4141

4242
@Before
4343
public void setUp() {
44-
appender = new InMemoryAppender(WizardTower.class);
44+
appender = new InMemoryAppender(IvoryTower.class);
4545
}
4646

4747
@After
@@ -58,8 +58,8 @@ public void testEnter() throws Exception {
5858
new Wizard("Merlin")
5959
};
6060

61-
final WizardTower tower = new WizardTower();
62-
for (final Wizard wizard : wizards) {
61+
IvoryTower tower = new IvoryTower();
62+
for (Wizard wizard : wizards) {
6363
tower.enter(wizard);
6464
}
6565

@@ -69,5 +69,4 @@ public void testEnter() throws Exception {
6969
assertTrue(appender.logContains("Merlin enters the tower."));
7070
assertEquals(4, appender.getLogSize());
7171
}
72-
7372
}

proxy/src/test/java/com/iluwatar/proxy/WizardTest.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,15 @@
2727
import static org.junit.Assert.assertEquals;
2828

2929
/**
30-
* Date: 12/28/15 - 9:02 PM
31-
*
32-
* @author Jeroen Meulemeester
30+
* Tests for {@link Wizard}
3331
*/
3432
public class WizardTest {
3533

3634
@Test
3735
public void testToString() throws Exception {
3836
final String[] wizardNames = {"Gandalf", "Dumbledore", "Oz", "Merlin"};
39-
for (final String name : wizardNames) {
37+
for (String name : wizardNames) {
4038
assertEquals(name, new Wizard(name).toString());
4139
}
4240
}
43-
4441
}

proxy/src/test/java/com/iluwatar/proxy/WizardTowerProxyTest.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
import static org.junit.Assert.assertTrue;
3232

3333
/**
34-
* Date: 12/28/15 - 9:18 PM
35-
*
36-
* @author Jeroen Meulemeester
34+
* Tests for {@link WizardTowerProxy}
3735
*/
3836
public class WizardTowerProxyTest {
3937

@@ -58,9 +56,9 @@ public void testEnter() throws Exception {
5856
new Wizard("Merlin")
5957
};
6058

61-
final WizardTowerProxy tower = new WizardTowerProxy();
62-
for (final Wizard wizard : wizards) {
63-
tower.enter(wizard);
59+
final WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
60+
for (Wizard wizard : wizards) {
61+
proxy.enter(wizard);
6462
}
6563

6664
assertTrue(appender.logContains("Gandalf enters the tower."));
@@ -69,5 +67,4 @@ public void testEnter() throws Exception {
6967
assertTrue(appender.logContains("Merlin is not allowed to enter!"));
7068
assertEquals(4, appender.getLogSize());
7169
}
72-
7370
}

0 commit comments

Comments
 (0)