Editing Combined Patterns New

Proxy


Objective

Provide a substitute for an object so that access to it can be controlled.

Function

Maintains a representative of an object

Structure

The Client must work with services and proxies through the same interface. This way, you can pass a proxy to any code that wait for an item of service. The proxy class has a reference field that points to an object of service.

The structure that meets this pattern is shown in Figure 1

Responsive image

Figure 1: UML Diagram Proxy Pattern

Applications

The use of the proxy pattern is recommended when

  • The system requires a remote representation for an object in a different place.

  • You want to hide the complexity of an object by representing it with a simple that does not require further knowledge in order to facilitate its use.

  • Objects must have different access points, controlling access to the original object, without this meaning that the object is instantiated in different places.

Design Patterns Collaborators

  • Both the Proxy and Decorator patterns have similar applications; however care should be taken since they serve different purposes, a Decorator adds one or more responsibilities to an object while a Proxy controls access to the object.

Scope of action

Applied at the object level.

Problem

In order to support the objects at the moment they are required, all objects must be pre-installed in such a way that they find ready for the client to use them; however, it implies a high resource consumption.

Solution

The proxy pattern allows you to control access to an object by instantiating it at the time the object is actually used, using a proxy" image object that is always present as a representation of the original, and is in charge of urging it only when required; in such a way that it puts provision a more versatile and sophisticated reference than a simple access point to an object; using three options: a "remote proxy" hiding the fact that a object resides in a different space or "virtual proxy" optimizing the creation of a object at the time it is required or both ways using references intelligent performing additional tasks when the object is accessed.

Diagram or Implementation

Responsive image

Figure 2: UML Diagram Proxy Pattern

Figure 2 explains the behavior of the proxy pattern using a diagram of sequence.

  • The client class requests an Object from the Factory component.

  • Component Factory creates a proxy that encapsulates the Object.

  • Client class runs the proxy created by the Factory component.

  • The Proxy class performs one or more actions prior to the execution of the Object.

  • The Proxy class delegates execution to the Object component.

  • The Proxy class performs one or more actions after the execution of the Object.

  • The proxy class returns a result.


Implementations of the proxy pattern:

    	
    		
"""
Provide a surrogate or placeholder for another object to control access
to it or add other responsibilities.
"""

import abc


class Subject(metaclass=abc.ABCMeta):
    """
    Define the common interface for RealSubject and Proxy so that a
    Proxy can be used anywhere a RealSubject is expected.
    """

    @abc.abstractmethod
    def request(self):
        pass


class Proxy(Subject):
    """
    Maintain a reference that lets the proxy access the real subject.
    Provide an interface identical to Subject's.
    """

    def __init__(self, real_subject):
        self._real_subject = real_subject

    def request(self):
        # ...
        self._real_subject.request()
        # ...


class RealSubject(Subject):
    """
    Define the real object that the proxy represents.
    """

    def request(self):
        pass


def main():
    real_subject = RealSubject()
    proxy = Proxy(real_subject)
    proxy.request()


if __name__ == "__main__":
    main()    	
    	
    	
    		
class ProxyBookList {
    private $bookList = NULL; 
    //bookList is not instantiated at construct time
    function __construct() {
    }
    function getBookCount() {
        if (NULL == $this->bookList) {
            $this->makeBookList(); 
        }
        return $this->bookList->getBookCount();
    }
    function addBook($book) {
        if (NULL == $this->bookList) {
            $this->makeBookList(); 
        }
        return $this->bookList->addBook($book);
    }  
    function getBook($bookNum) {
        if (NULL == $this->bookList) {
            $this->makeBookList();
        } 
        return $this->bookList->getBook($bookNum);
    }
    function removeBook($book) {
        if (NULL == $this->bookList) {
            $this->makeBookList();
        } 
        return $this->bookList->removeBook($book);
    }
    //Create 
    function makeBookList() {
        $this->bookList = new bookList();
    }
}

class BookList {
    private $books = array();
    private $bookCount = 0;
    public function __construct() {
    }
    public function getBookCount() {
        return $this->bookCount;
    }
    private function setBookCount($newCount) {
        $this->bookCount = $newCount;
    }
    public function getBook($bookNumberToGet) {
        if ( (is_numeric($bookNumberToGet)) && ($bookNumberToGet <= $this->getBookCount())) {
            return $this->books[$bookNumberToGet];
        } else {
           return NULL;
        }
    }
    public function addBook(Book $book_in) {
        $this->setBookCount($this->getBookCount() + 1);
        $this->books[$this->getBookCount()] = $book_in;
        return $this->getBookCount();
    }
    public function removeBook(Book $book_in) {
        $counter = 0;
        while (++$counter <= $this->getBookCount()) {
          if ($book_in->getAuthorAndTitle() == $this->books[$counter]->getAuthorAndTitle()) {
            for ($x = $counter; $x < $this->getBookCount(); $x++) {
              $this->books[$x] = $this->books[$x + 1];
          }
          $this->setBookCount($this->getBookCount() - 1);
        }
      }
      return $this->getBookCount();
    }
}

class Book {
    private $author;
    private $title;
    function __construct($title_in, $author_in) {
      $this->author = $author_in;
      $this->title  = $title_in;
    }
    function getAuthor() {
        return $this->author;
    }
    function getTitle() {
        return $this->title;
    }
    function getAuthorAndTitle() {
      return $this->getTitle().' by '.$this->getAuthor();
    }
}

  writeln( 'BEGIN TESTING PROXY PATTERN';
  writeln('');
 
  $proxyBookList = new ProxyBookList();
  $inBook = new Book('PHP for Cats','Larry Truett');
  $proxyBookList->addBook($inBook);
 
  writeln('test 1 - show the book count after a book is added');
  writeln($proxyBookList->getBookCount());
  writeln('');
 
  writeln('test 2 - show the book');
  $outBook = $proxyBookList->getBook(1);
  writeln($outBook->getAuthorAndTitle()); 
  writeln('');
 
  $proxyBookList->removeBook($outBook);
 
  writeln('test 3 - show the book count after a book is removed');
  writeln($proxyBookList->getBookCount());
  writeln('');

  writeln('END TESTING PROXY PATTERN');

  function writeln($line_in) {
    echo $line_in."
"; }
    	
    		
// 5. To support plug-compatibility between
// the wrapper and the target, create an interface
interface SocketInterface {
    String readLine();
    void  writeLine(String str);
    void  dispose();
}

class SocketProxy implements SocketInterface {
    // 1. Create a "wrapper" for a remote,
    // or expensive, or sensitive target
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    public SocketProxy(String host, int port, boolean wait) {
        try {
            if (wait) {
                // 2. Encapsulate the complexity/overhead of the target in the wrapper
                ServerSocket server = new ServerSocket(port);
                socket = server.accept();
            } else {
                socket = new Socket(host, port);
            }
            in  = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    public String readLine() {
        String str = null;
        try {
            str = in.readLine();
        } catch( IOException e ) {
            e.printStackTrace();
        }
        return str;
    }

    public void writeLine(String str) {
        // 4. The wrapper delegates to the target
        out.println(str);
    }

    public void dispose() {
        try {
            socket.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}

public class ProxyDemo {
    public static void main( String[] args ) {
        // 3. The client deals with the wrapper
        SocketInterface socket = new SocketProxy( "127.0.0.1", 8080, args[0].equals("first") ? true : false );
        String  str;
        boolean skip = true;
        while (true) {
            if (args[0].equals("second") && skip) {
                skip = !skip;
            } else {
                str = socket.readLine();
                System.out.println("Receive - " + str);
                if (str.equals(null)) {
                    break;
                }
            }
            System.out.print( "Send ---- " );
            str = new Scanner(System.in).nextLine();
            socket.writeLine( str );
            if (str.equals("quit")) {
                break;
            }
        }
        socket.dispose();
    }
}