Skeleton of GOF's Design Pattern


PROXYの骸骨

PROXY

生成にコストのかかる もしくは 生成に注意を払わなければならないオブジェクトに対するアクセスを制御するために、そのオブジェクトとそっくりな代理を提供するパターンです。


■ 『PROXYの骸骨』の構造


■ 『PROXYの骸骨』 プログラム・コード

□ Java2版
// Copyright(C) 2000-2003 Yoshinori Oota All rights reserved.

public class ProxySample {
    static Subject Create() {
        return new ProxySubject();
    }
    static public void main(String[] args) { 
        Subject subject = Create();
        subject.Request();
        subject.Request(); 
    } 
}

abstract class Subject { 
    abstract public void Request(); 
}

class RealSubject extends Subject { 
    private String _str = "very long text -------->";
    public void Request() {
        System.out.println(_str); 
    } 
}

class ProxySubject extends Subject { 
    private RealSubject _subject = null;
    public void Request() { 
        if (_subject == null) { 
            System.out.print("(please wait...)   ");
            _subject = new RealSubject();
        }
        _subject.Request(); 
    } 
}

○ C++版
// Copyright(C) 2003 Yoshinori Oota All rights reserved.

#include <iostream>
using namespace std;

class Subject {
public:
    Subject();
    virtual ~Subject();
    virtual void Request() = 0;
};

class RealSubject : public Subject {
public:
    virtual ~RealSubject();
    virtual void Request();
protected:
    friend class ProxySubject;
    RealSubject();
private:
    string value_;
};

class ProxySubject : public Subject {
public:
    ProxySubject();
    virtual ~ProxySubject();
    virtual void Request();
private:
    RealSubject* subject_;
};

Subject::Subject() { }
Subject::~Subject() { }
RealSubject::RealSubject() : value_("very long text -----> ") { }
RealSubject::~RealSubject() { }
void RealSubject::Request() {
    cout << value_ << endl;
}
ProxySubject::ProxySubject() : subject_(NULL) { }
ProxySubject::~ProxySubject() {
    delete subject_;
    subject_ = NULL;
}
void ProxySubject::Request() {
    if (subject_ == NULL) {
        cout << "(please wait....)    ";
        subject_ = new RealSubject();
    }
    subject_->Request();
}


Subject* Create() {
    return new ProxySubject();
}

int main() {
    Subject* subject = Create();
    subject->Request();
    subject->Request();
    delete subject;
}

○ C版
/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
enum CLASS_TYPE { REAL ,PROXY };

struct Subject;

/* Suject Interface */
struct Subject {
    char* str_;
    struct Subject* subject_;
    void (*Request)(struct Subject* subject);
};

struct Subject* New_Subject(enum CLASS_TYPE type);
void Delete_Subject(struct Subject* subject);
void Subject_OriginalMethod(struct Subject* subject);
void Subject_ProxyMethod(struct Subject* subject);

/* Subject Class Implementation */
struct Subject* New_Subject (enum CLASS_TYPE type) {
    struct Subject* subject = NULL;
    subject = (struct Subject*)malloc(sizeof(struct Subject));
    switch(type) {
    case REAL:
        subject->str_ = "very long text -----";
        subject->subject_ = NULL;
        subject->Request = &Subject_OriginalMethod;
        break;
    case PROXY:
        subject->str_ = NULL;
        subject->subject_ = NULL;
        subject->Request = &Subject_ProxyMethod;
        break;
    }
    return subject;
}

void Delete_Subject(struct Subject* subject) {
    if (subject == NULL) {
        return;
    }
    Delete_Subject(subject->subject_);
    free(subject);
    subject = NULL;
    return;
}

void Subject_OriginalMethod(struct Subject* subject) {
    printf("Real MSG: %s\n", subject->str_);
    return;
}

void Subject_ProxyMethod(struct Subject* subject) {
    if (subject->subject_ == NULL) {
        printf("PROXY MSG: please wait...\n");
        subject->subject_ = New_Subject(REAL);
    }
    subject->subject_->Request(subject->subject_);
    return;
}

int main() {
    struct Subject* subject = NULL;

    subject = New_Subject(PROXY);
    subject->Request(subject);
    subject->Request(subject);

    Delete_Subject(subject);

    return 0;
}


改訂履歴

2009.2.21 C言語版を追加
     
     

ご意見、ご感想はこちらまで。

Copyright(C) 2000-2009 Yoshinori Oota All rights reserved.

本ホームページのリンクは自由です。複製、転載される場合は、必ず著者までご連絡をください。