Skip to content

Commit 8a8670b

Browse files
author
Jarry
committed
add proxy for c
1 parent 375edc5 commit 8a8670b

File tree

9 files changed

+355
-6
lines changed

9 files changed

+355
-6
lines changed

prototype-pattern/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ public class Application {
212212

213213
## 基础原型抽象类
214214

215-
```func.h 基础头文件
215+
```c
216+
// func.h 基础头文件
216217
#include <stdio.h>
217218
#include <ctype.h>
218219
#include <stdlib.h>

proxy-pattern/README.md

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 【代理设计模式详解】Java/JS/Go/Python/TS不同语言实现
1+
# 【代理设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
22

33
# 简介
44
代理模式(Proxy Pattern)是一种结构型设计模式,用一个类来代理另一个类或几个类的功能。
@@ -22,7 +22,7 @@
2222
<img src="../docs/uml/proxy-pattern.png">
2323

2424

25-
# 代码
25+
# Java代码
2626

2727
## 代理接口类
2828
```java
@@ -98,5 +98,152 @@ public class RealImage implements Image {
9898
// 再调用一次,不会重复实例化
9999
image.display();
100100
```
101+
102+
# Go代码
103+
104+
## 代理接口类
105+
```go
106+
// Image.go 定义一个接口供代理和实际调用来使用
107+
type Image interface {
108+
Init(fileName string)
109+
Display()
110+
}
111+
112+
```
113+
114+
## 功能代理类
115+
```go
116+
// ProxyImage.go 代理类也实现了基础接口
117+
type ProxyImage struct {
118+
fileName string
119+
// 直接聚合真实类
120+
// realImage RealImage
121+
// 聚合接口
122+
realImage Image
123+
}
124+
125+
// 设置文件名称
126+
func (p *ProxyImage) SetFileName(fileName string) {
127+
p.fileName = fileName
128+
}
129+
130+
func (p *ProxyImage) Display() {
131+
fmt.Println("ProxyImage::Display() " + p.fileName)
132+
if p.realImage == nil {
133+
p.realImage = &RealImage{}
134+
p.realImage.Init(p.fileName)
135+
}
136+
// 代理类调用真实类的方法
137+
p.realImage.Display()
138+
}
139+
140+
```
141+
142+
## 真实功能类
143+
```go
144+
// RealImage.go 真实类也实现基础代理接口
145+
type RealImage struct {
146+
fileName string
147+
}
148+
149+
// 在初始化时执行内部逻辑
150+
func (r *RealImage) Init(fileName string) {
151+
r.fileName = fileName
152+
r.LoadFromDisk(fileName)
153+
}
154+
155+
func (r *RealImage) Display() {
156+
fmt.Println("RealImage::Display() " + r.fileName)
157+
}
158+
159+
// 这个方法只是内部使用
160+
func (r *RealImage) LoadFromDisk(fileName string) {
161+
fmt.Println("RealImage::LoadFromDisk() " + fileName)
162+
}
163+
```
164+
165+
## 测试调用
166+
```go
167+
func main() {
168+
fmt.Println("test start:")
169+
/**
170+
* 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
171+
* 这样真实类和调用方之间有一个代理屏障,保证了安全
172+
* 同时真实的类如果初始化过,就不再初始化,提升了性能
173+
*/
174+
175+
// 声明代理类来执行真实类的能力
176+
var image = &src.ProxyImage{}
177+
image.SetFileName("001.jpg")
178+
179+
// 代理类执行真实类的能力
180+
image.Display()
181+
182+
// 再调用一次,真实类不会重复实例化
183+
image.Display()
184+
}
185+
```
186+
187+
# C代码简版
188+
```c
189+
// simple_proxy.c
190+
#include <stdio.h>
191+
192+
// 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
193+
194+
// 定义接口
195+
typedef struct Interface
196+
{
197+
void (*method)(struct Interface *interface);
198+
} Interface;
199+
200+
// 实现接口的具体类
201+
typedef struct Concrete
202+
{
203+
void (*method)(struct Concrete *interface);
204+
} Concrete;
205+
206+
void real_method(struct Concrete *interface)
207+
{
208+
printf("调用真实方法 real_method.\n");
209+
}
210+
211+
// 代理类,继承接口,聚合具体类实例
212+
typedef struct Proxy
213+
{
214+
struct Interface *real_subject;
215+
} Proxy;
216+
217+
// 代理类方法实现,通过聚合的具体类实例来调用具体类的方法
218+
void proxy_method(struct Interface *interface)
219+
{
220+
struct Proxy *p = (struct Proxy *)interface;
221+
p->real_subject->method((struct Interface *)p);
222+
}
223+
224+
int main()
225+
{
226+
// 创建具体类实例
227+
struct Concrete real_subject = {
228+
.method = &real_method,
229+
};
230+
231+
// 创建代理类实例并聚合具体类实例
232+
struct Proxy proxy_instance = {
233+
.real_subject = (struct Interface *)&real_subject,
234+
};
235+
236+
// 将代理类的方法指针指向代理类的方法实现
237+
struct Interface proxy_interface = {
238+
.method = &proxy_method,
239+
};
240+
241+
// 通过代理类的接口调用具体类方法
242+
proxy_interface.method((struct Interface *)&proxy_instance);
243+
244+
return 0;
245+
}
246+
247+
```
101248
## 更多语言版本
102249
不同语言实现设计模式:[https://github.com/microwind/design-pattern](https://github.com/microwind/design-pattern)

proxy-pattern/c/src/func.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <stdio.h>
2+
#include <ctype.h>
3+
#include <stdlib.h>
4+
#include <stdbool.h>
5+
#include <string.h>
6+
7+
typedef struct Image Image;
8+
typedef struct ProxyImage ProxyImage;
9+
typedef struct RealImage RealImage;
10+
11+
// 定义一个接口供代理和实际调用来使用
12+
typedef struct Image
13+
{
14+
char file_name[200];
15+
RealImage *real_image;
16+
void (*set_file_name)(Image *image, char *file_name);
17+
void (*display)(Image *image);
18+
} Images;
19+
20+
void image_set_file_name(Image *image, char *file_name);
21+
22+
// 代理类也实现了基础接口
23+
typedef struct ProxyImage
24+
{
25+
char file_name[200];
26+
// 代理类聚合真实类
27+
RealImage *real_image;
28+
void (*set_file_name)(ProxyImage *image, char *file_name);
29+
void (*display)(ProxyImage *image);
30+
} ProxyImage;
31+
ProxyImage *proxy_image_constructor(char *file_name);
32+
33+
// 真实类实现基础接口
34+
typedef struct RealImage
35+
{
36+
char file_name[200];
37+
RealImage *real_image;
38+
void (*set_file_name)(RealImage *image, char *file_name);
39+
void (*display)(RealImage *image);
40+
} RealImage;
41+
RealImage *real_image_constructor(char *file_name);
42+
void real_image_init(RealImage *image, char *file_name);

proxy-pattern/c/src/image.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "func.h"
2+
3+
// 基础接口,供代理类和真实类实现,定义在head
4+
5+
// 设置文件名称
6+
void image_set_file_name(Image *image, char *file_name)
7+
{
8+
strcpy(image->file_name, file_name);
9+
}

proxy-pattern/c/src/proxy_image.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "func.h"
2+
3+
// 代理类实现了基础接口
4+
5+
void proxy_image_display(ProxyImage *image)
6+
{
7+
printf("\r\n ProxyImage::display() [file_name=%s]", image->file_name);
8+
if (image->real_image == NULL)
9+
{
10+
image->real_image = real_image_constructor(image->file_name);
11+
real_image_init(image->real_image, image->file_name);
12+
}
13+
// 代理类调用真实类的display
14+
image->real_image->display(image->real_image);
15+
}
16+
17+
ProxyImage *proxy_image_constructor(char *file_name)
18+
{
19+
printf("\r\n proxy_image_constructor() [构建ProxyImage]");
20+
Image *image = (Image *)malloc(sizeof(Image));
21+
strcpy(image->file_name, file_name);
22+
image->set_file_name = &image_set_file_name;
23+
ProxyImage *proxy_image = (ProxyImage *)image;
24+
proxy_image->display = &proxy_image_display;
25+
return proxy_image;
26+
}

proxy-pattern/c/src/real_image.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include "func.h"
2+
3+
// 真实类实现基础接口
4+
5+
// 这个方法只是内部使用
6+
void real_image_load_from_disk(RealImage *image, char *file_name)
7+
{
8+
printf("\r\n RealImage::load_from_disk() [file_name=%s]", file_name);
9+
}
10+
11+
// 在初始化时执行内部逻辑
12+
void real_image_init(RealImage *image, char *file_name)
13+
{
14+
strcpy(image->file_name, file_name);
15+
real_image_load_from_disk(image, file_name);
16+
}
17+
18+
void real_image_display(RealImage *image)
19+
{
20+
printf("\r\n RealImage::display() [file_name=%s]", image->file_name);
21+
}
22+
23+
RealImage *real_image_constructor(char *file_name)
24+
{
25+
printf("\r\n real_image_constructor() [构建RealImage]");
26+
Image *image = (Image *)malloc(sizeof(Image));
27+
strcpy(image->file_name, file_name);
28+
image->set_file_name = &image_set_file_name;
29+
RealImage *real_image = (RealImage *)image;
30+
real_image->real_image = NULL;
31+
real_image->display = &real_image_display;
32+
return real_image;
33+
}

proxy-pattern/c/test/simple_proxy.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <stdio.h>
2+
3+
// 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
4+
5+
// 定义接口
6+
typedef struct Interface
7+
{
8+
void (*method)(struct Interface *interface);
9+
} Interface;
10+
11+
// 实现接口的具体类
12+
typedef struct Concrete
13+
{
14+
void (*method)(struct Concrete *interface);
15+
} Concrete;
16+
17+
void real_method(struct Concrete *interface)
18+
{
19+
printf("调用真实方法 real_method.\n");
20+
}
21+
22+
// 代理类,继承接口,聚合具体类实例
23+
typedef struct Proxy
24+
{
25+
struct Interface *real_subject;
26+
} Proxy;
27+
28+
// 代理类方法实现,通过聚合的具体类实例来调用具体类的方法
29+
void proxy_method(struct Interface *interface)
30+
{
31+
struct Proxy *p = (struct Proxy *)interface;
32+
p->real_subject->method((struct Interface *)p);
33+
}
34+
35+
int main()
36+
{
37+
// 创建具体类实例
38+
struct Concrete real_subject = {
39+
.method = &real_method,
40+
};
41+
42+
// 创建代理类实例并聚合具体类实例
43+
struct Proxy proxy_instance = {
44+
.real_subject = (struct Interface *)&real_subject,
45+
};
46+
47+
// 将代理类的方法指针指向代理类的方法实现
48+
struct Interface proxy_interface = {
49+
.method = &proxy_method,
50+
};
51+
52+
// 通过代理类的接口调用具体类方法
53+
proxy_interface.method((struct Interface *)&proxy_instance);
54+
55+
return 0;
56+
}

proxy-pattern/c/test/test.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "../src/func.h"
2+
3+
int main(void)
4+
{
5+
printf("test start:\r\n");
6+
/**
7+
* 代理模式就是用一个类来代理另一个类或几个类的功能,以便隔绝外部客户和内部真实类
8+
* 这样真实类和调用方之间有一个代理屏障,保证了安全
9+
* 同时真实的类如果初始化过,就不再初始化,提升了性能
10+
*/
11+
12+
// 声明代理类来执行真实类的能力
13+
Image *image = (Image *)proxy_image_constructor("abc.png");
14+
image->set_file_name(image, "001.jpg");
15+
16+
// 代理类执行真实类的能力
17+
image->display(image);
18+
19+
// 再调用一次,不会重复实例化
20+
image->display(image);
21+
}
22+
23+
/**
24+
jarry@jarrys-MacBook-Pro c % gcc test/test.c ./src下*.c
25+
jarry@jarrys-MacBook-Pro c % ./a.out
26+
test start:
27+
28+
proxy_image_constructor() [构建ProxyImage]
29+
ProxyImage::display() [file_name=001.jpg]
30+
real_image_constructor() [构建RealImage]
31+
RealImage::load_from_disk() [file_name=001.jpg]
32+
RealImage::display() [file_name=001.jpg]
33+
ProxyImage::display() [file_name=001.jpg]
34+
RealImage::display() [file_name=001.jpg]%
35+
*/

0 commit comments

Comments
 (0)