Skip to content

Commit ef88974

Browse files
committed
added 2 examples image example and router example
1 parent 4b73171 commit ef88974

File tree

9 files changed

+398
-0
lines changed

9 files changed

+398
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Image Example From GOF
2+
3+
Consider a document editor that can embed graphical objects in a document.
4+
5+
- Some graphical objects, like large raster images, can be expensive to create.
6+
- But opening a document should be fast,
7+
- so we should avoid creating all the expensive objects at once when the document is opened.
8+
9+
> This isn't necessary anyway, because not all of these objects will be visible in the document at the same time.
10+
---
11+
These constraints would suggest creating each expensive object on demand, which in this case occurs when an image becomes visible.
12+
1. But what do we put in the document in place of the image?
13+
2. And how can we hide the fact that the image is created on demand so that we don't complicate the editor's implementation? This optimization shouldn't impact the rendering and formatting code,
14+
15+
> - The solution is to use another object,
16+
> - an image proxy, that acts as a stand-in for the real image.
17+
> - The proxy acts just like the image and takes care of instantiating it when it's required.
18+
19+
<div align="center">
20+
<img src="example_assets/proxy016.gif">
21+
</div>
22+
23+
`The imageProxy`:
24+
- creates the real image only when the document editor asks it to display itself by invoking its Draw operation.
25+
- The proxy forwards subsequent requests directly to the image. It must therefore keep a reference to the image after creating it.
26+
27+
---
28+
29+
Let's assume that images are stored in separate files.
30+
- In this case we can use the file name as the reference to the real object.
31+
- The proxy also stores
32+
1. its extent (png, jpg, gif),
33+
2. its width and height.
34+
> The extent lets the proxy respond to requests for its size from the formatter without actually instantiating the image.
35+
36+
The following class diagram illustrates this example in more detail.
37+
<div align="center">
38+
<img src="example_assets/proxy-eg.gif">
39+
</div>
40+
41+
- `documentEditor`:
42+
accesses embedded images through the interface defined by the abstract Graphic class.
43+
- `ImageProxy`
44+
1. is a class for images that are created on demand.
45+
2. maintains the file name as a reference to the image on disk. The file name is passed as an argument to the ImageProxy constructor.
46+
3. also stores the bounding box of the image and a reference to the real Image instance.
47+
- This reference won't be valid until the proxy instantiates the real image.
48+
- The Draw operation makes sure the image is instantiated before forwarding it the request.
49+
- GetExtent forwards the request to the image only if it's instantiated; otherwise ImageProxy returns the extent it stores.
50+
51+
example Structure:
52+
<img src="example_assets/proxy-eg.gif">
53+
<img src="example_assets/proxy016.gif">
54+
55+
56+
57+
<table align="center">
58+
<tr>
59+
<th>class</th>
60+
<th>What it do </th>
61+
</tr>
62+
<tr>
63+
<td>Proxy (ImageProxy)</td>
64+
<td>
65+
66+
1. maintains a reference that lets the proxy access the real subject.
67+
- Proxy may refer to a Subject if the RealSubject and Subject interfaces are the same.
68+
69+
1. provides an interface identical to Subject's so that a proxy can by substituted for the real subject.
70+
1. controls access to the real subject and may be responsible for creating and deleting it.
71+
1. other responsibilities depend on the kind of proxy:
72+
- remote proxies are responsible for encoding a request and its arguments and for sending the encoded request to the real subject in a different address space.
73+
- virtual proxies may cache additional information about the real subject so that they can postpone accessing it. For example, the ImageProxy from the Motivation caches the real image's extent.
74+
- protection proxies check that the caller has the access permissions required to perform a request.
75+
</td>
76+
</tr>
77+
<tr>
78+
<td>Subject (Graphic)</td>
79+
<td> defines the common interface for RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.</td>
80+
</tr>
81+
<tr>
82+
<td>RealSubject (Image) </td>
83+
<td> defines the real object that the proxy represents. </td>
84+
</tr>
85+
</table>
86+
87+
88+
## code
89+
90+
```dart
91+
92+
abstract class Graphic {
93+
void displayImage();
94+
}
95+
96+
// On System A
97+
class RealImage implements Graphic {
98+
final String _filename;
99+
100+
RealImage(this._filename) {
101+
_loadImageFromDisk();
102+
}
103+
104+
/// Loads the image from the disk
105+
void _loadImageFromDisk() => print("Loading " + _filename);
106+
107+
/// Displays the image
108+
void displayImage() => print("Displaying " + _filename);
109+
}
110+
111+
// On System B
112+
class ProxyImage implements Graphic {
113+
final String _filename;
114+
RealImage? _image;
115+
116+
ProxyImage(this._filename);
117+
118+
/// Displays the image
119+
void displayImage() {
120+
if (_image == null) {
121+
_image = RealImage(_filename);
122+
} else {
123+
_image!.displayImage();
124+
}
125+
}
126+
}
127+
128+
```
129+
### Testing
130+
```dart
131+
132+
void main(List<String> arguments) {
133+
Graphic image1 = ProxyImage("HiRes_10MB_Photo1");
134+
Graphic image2 = ProxyImage("HiRes_10MB_Photo2");
135+
136+
print("--- image1----");
137+
image1.displayImage(); // loading necessary
138+
image1.displayImage(); // loading unnecessary
139+
print("--- image2----");
140+
image2.displayImage(); // loading necessary
141+
image2.displayImage(); // loading unnecessary
142+
print("--- image1----");
143+
print("image1.displayImage() again = will display without loading ");
144+
image1.displayImage(); // loading unnecessary
145+
}
146+
147+
// Output
148+
149+
// --- image1----
150+
// Loading HiRes_10MB_Photo1
151+
// Displaying HiRes_10MB_Photo1
152+
// --- image2----
153+
// Loading HiRes_10MB_Photo2
154+
// Displaying HiRes_10MB_Photo2
155+
// --- image1----
156+
// image1.displayImage() again = will display without loading
157+
// Displaying HiRes_10MB_Photo1
158+
159+
160+
```
Loading
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
abstract class Graphic {
2+
void displayImage();
3+
}
4+
5+
// On System A
6+
class RealImage implements Graphic {
7+
final String _filename;
8+
9+
RealImage(this._filename) {
10+
_loadImageFromDisk();
11+
}
12+
13+
/// Loads the image from the disk
14+
void _loadImageFromDisk() => print("Loading " + _filename);
15+
16+
/// Displays the image
17+
void displayImage() => print("Displaying " + _filename);
18+
}
19+
20+
// On System B
21+
class ProxyImage implements Graphic {
22+
final String _filename;
23+
RealImage? _image;
24+
25+
ProxyImage(this._filename);
26+
27+
/// Displays the image
28+
void displayImage() {
29+
if (_image == null) {
30+
_image = RealImage(_filename);
31+
} else {
32+
_image!.displayImage();
33+
}
34+
}
35+
}
36+
37+
// Test method
38+
void main(List<String> arguments) {
39+
Graphic image1 = ProxyImage("HiRes_10MB_Photo1");
40+
Graphic image2 = ProxyImage("HiRes_10MB_Photo2");
41+
42+
print("--- image1----");
43+
image1.displayImage(); // loading necessary
44+
image1.displayImage(); // loading unnecessary
45+
print("--- image2----");
46+
image2.displayImage(); // loading necessary
47+
image2.displayImage(); // loading unnecessary
48+
print("--- image1----");
49+
print("image1.displayImage() again = will display without loading ");
50+
image1.displayImage(); // loading unnecessary
51+
}
52+
53+
// Output
54+
55+
// --- image1----
56+
// Loading HiRes_10MB_Photo1
57+
// Displaying HiRes_10MB_Photo1
58+
// --- image2----
59+
// Loading HiRes_10MB_Photo2
60+
// Displaying HiRes_10MB_Photo2
61+
// --- image1----
62+
// image1.displayImage() again = will display without loading
63+
// Displaying HiRes_10MB_Photo1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Client {
2+
String name;
3+
Client(this.name);
4+
}
5+
6+
class Manager extends Client {
7+
Manager({String name = 'manager'}) : super(name);
8+
}
9+
10+
class NormalClient extends Client {
11+
NormalClient([String name = 'Normal Client']) : super(name);
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import 'clients.dart';
2+
import 'router.dart';
3+
import 'router_proxy.dart';
4+
import 'routing_components.dart';
5+
6+
void main(List<String> args) {
7+
List<Client> allowedRouterUsers = [Manager()];
8+
List<Route> routes = [
9+
Route('http://www.google.com', '152.233.22.1'),
10+
Route('http://www.abc.com', '93.23.2.232'),
11+
Route('http://www.xyz.com', '18.87.198.1'),
12+
];
13+
14+
RoutingTable table = RoutingTable(routes);
15+
Firewall firewall = Firewall();
16+
ConnectionManager connectionManager = ConnectionManager();
17+
18+
print('----------------------------------');
19+
print('----------testing without proxy----------');
20+
Router router = Router(connectionManager, table, firewall);
21+
test(router);
22+
23+
print('\n----------------------------------');
24+
print('----------proxy testing with allowed client----------');
25+
RouterInterface proxyRouterAllowed =
26+
RouterProxy(router, allowedRouterUsers, Manager());
27+
test(proxyRouterAllowed);
28+
29+
print('\n----------------------------------');
30+
print('----------proxy testing with not allowed client----------');
31+
RouterInterface proxyRouterNotAllowed =
32+
RouterProxy(router, allowedRouterUsers, NormalClient());
33+
test(proxyRouterNotAllowed);
34+
}
35+
36+
void test(RouterInterface router) {
37+
if (router.resolve('http://www.google.com')) {
38+
print("valid Resolve");
39+
router.stream();
40+
print("Stream Done!");
41+
} else {
42+
print("invalid Resolve!");
43+
}
44+
print("\n -------------another link-------------");
45+
if (router.resolve('http://www.not avalable.com')) {
46+
print("valid Resolve");
47+
router.stream();
48+
print("Stream Done!");
49+
} else {
50+
print("invalid Resolve!");
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import 'routing_components.dart';
2+
3+
abstract class RouterInterface {
4+
bool resolve(String url);
5+
void stream();
6+
}
7+
8+
class Router implements RouterInterface {
9+
ConnectionManager _connectionManager;
10+
RoutingTable _table;
11+
Firewall _firewall;
12+
13+
Router(this._connectionManager, this._table, this._firewall);
14+
15+
@override
16+
bool resolve(String _url) {
17+
Route? _route = _table.mapUrlToIPAddress(_url);
18+
if (_route != null) {
19+
_connect(_route.getIpAddress());
20+
} else {
21+
print("Route was not found.");
22+
return false;
23+
}
24+
return true;
25+
}
26+
27+
@override
28+
void stream() {
29+
List<String> _packets = [
30+
'Package one is clean',
31+
'Package two is clean',
32+
'Package three is __BAD__',
33+
'Package four is __BAD__',
34+
];
35+
36+
for (String packet in _packets) {
37+
if (_firewall.isValidPacket(packet)) {
38+
print("$packet.");
39+
} else {
40+
print("Dropping a packet.");
41+
}
42+
}
43+
44+
_terminate();
45+
}
46+
47+
void _terminate() => _connectionManager.terminate();
48+
void _connect(String _ipAddress) => _connectionManager.connectTo(_ipAddress);
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import 'router.dart';
2+
import 'clients.dart';
3+
4+
class RouterProxy implements RouterInterface {
5+
RouterInterface _router;
6+
Client _app;
7+
List<Client> _accessControlList;
8+
9+
RouterProxy(this._router, this._accessControlList, this._app);
10+
11+
bool resolve(String $url) {
12+
if (isAllowedClient()) {
13+
return _router.resolve($url);
14+
} else {
15+
print("Hi:${_app.name}: This Client can not use the router");
16+
}
17+
return false;
18+
}
19+
20+
stream() {
21+
if (isAllowedClient()) {
22+
_router.stream();
23+
} else {
24+
print("Hi:${_app.name}: This Client can not use the router");
25+
}
26+
}
27+
28+
bool isAllowedClient() =>
29+
_accessControlList.any((Client c) => c.name == _app.name);
30+
}

0 commit comments

Comments
 (0)