디자인 패턴을 이해하고 사용하면 좋은 객체 지향 프로그래밍 습관을 기르는 동시에 실제 응용 프로그램에서는 물 속의 물고기처럼 편안함을 느낄 수 있습니다.
프록시는 더 유용한 모드이며 다양한 변형이 있습니다. 프록시는 프록시 서버와 같은 개념을 의미할 수 있습니다. 설명은 다음과 같습니다. 출발지와 목적지 사이에 중간층이 있는데, 이는 대행사를 의미합니다.
디자인 패턴 정의: 다른 개체에 대한 프록시를 제공하여 이 개체에 대한 액세스를 제어합니다.
프록시 모드를 사용하는 이유
1. 인증 메커니즘 서로 다른 수준의 사용자는 동일한 개체에 대해 서로 다른 액세스 권한을 갖습니다. 예를 들어 Jive 포럼 시스템에서는 프록시를 사용하여 인증 메커니즘을 제어합니다. 포럼에 액세스하는 사람에는 등록된 사용자와 방문자(등록되지 않은 사용자)라는 두 가지 유형이 있습니다. Jive는 ForumProxy와 같은 에이전트를 사용하여 포럼에 대한 이 두 사용자의 액세스 권한을 제어합니다.
2. 클라이언트는 객체를 직접 조작할 수는 없지만 해당 객체와 상호 작용해야 합니다.
두 가지 구체적인 상황을 예로 들어보겠습니다.
1. 물체가 매우 큰 그림이고 표시하는 데 시간이 오래 걸리는 경우 그림이 문서에 포함될 때 사용합니다. 이 문서를 열려면 편집기나 브라우저가 필요합니다. 문서를 매우 빠르게 열어야 하며 큰 이미지가 처리될 때까지 기다릴 수 없습니다. 이 경우 실제 사진을 대체할 사진 프록시를 만들어야 합니다.
2. 객체가 인터넷상의 원격 서버에 있는 경우 네트워크 속도로 인해 객체를 직접 조작하는 것이 느려질 수 있으므로 먼저 Proxy를 사용하여 객체를 교체할 수 있습니다.
요컨대, 값비싼 객체는 사용될 때만 생성되어야 한다는 원칙입니다. 이 원칙은 귀중한 Java 메모리를 많이 절약할 수 있습니다. 따라서 일부 사람들은 Java가 리소스와 메모리를 소비한다고 생각합니다. 이는 프로그래밍 아이디어와 일정한 관계가 있다고 생각합니다.
프록시 모드 사용 방법
자이브 포럼 시스템을 예로 들면, 포럼 시스템에 접속하는 사용자 유형은 등록된 일반 사용자, 포럼 관리자, 시스템 관리자, 방문자 등 다양합니다. . 등록된 일반 사용자만이 발언할 수 있습니다. 포럼 관리자는 자신이 권한을 부여받은 포럼을 관리할 수 있습니다. 시스템 관리자는 모든 업무 등을 관리할 수 있습니다. 이러한 권한 분할 및 관리는 프록시를 사용하여 완료됩니다.
포럼은 Jive의 핵심 인터페이스입니다. 포럼 이름, 포럼 설명 가져오기 및 수정, 게시물 게시, 삭제 및 편집 등 포럼 운영과 관련된 주요 동작이 포럼에 표시됩니다.
다양한 수준의 권한을 가진 사용자는 ForumPermissions:
public class ForumPermissions implements Cacheable { /** * Permission to read object. */ public static final int READ = 0; /** * Permission to administer the entire sytem. */ public static final int SYSTEM_ADMIN = 1; /** * Permission to administer a particular forum. */ public static final int FORUM_ADMIN = 2; /** * Permission to administer a particular user. */ public static final int USER_ADMIN = 3; /** * Permission to administer a particular group. */ public static final int GROUP_ADMIN = 4; /** * Permission to moderate threads. */ public static final int MODERATE_THREADS = 5; /** * Permission to create a new thread. */ public static final int CREATE_THREAD = 6; /** * Permission to create a new message. */ public static final int CREATE_MESSAGE = 7; /** * Permission to moderate messages. */ public static final int MODERATE_MESSAGES = 8; ..... public boolean isSystemOrForumAdmin() { return (values[FORUM_ADMIN] || values[SYSTEM_ADMIN]); } ..... }
에 정의되어 있습니다. 따라서 포럼의 다양한 작업 권한은 ForumPermissions 인터페이스 Forum: ForumProxy의 구현으로 정의된 사용자 수준과 관련됩니다. 이 서신을 연결합니다. 예를 들어 포럼의 이름을 수정하려면 포럼 관리자나 시스템 관리자만 수정할 수 있습니다. 코드는 다음과 같습니다.
public class ForumProxy implements Forum { private ForumPermissions permissions; private Forum forum; this.authorization = authorization; public ForumProxy(Forum forum, Authorization authorization, ForumPermissions permissions){ this.forum = forum; this.authorization = authorization; this.permissions = permissions; } ..... public void setName(String name) throws UnauthorizedException, ForumAlreadyExistsException{ //只有是系统或论坛管理者才可以修改名称 if (permissions.isSystemOrForumAdmin()) { forum.setName(name); } else { throw new UnauthorizedException(); } } ... }
그리고 DbForum은 Forum 인터페이스의 실제 구현입니다. 포럼의 예:
public class DbForum implements Forum, Cacheable { ... public void setName(String name) throws ForumAlreadyExistsException { .... this.name = name; //这里真正将新名称保存到数据库中 saveToDb(); .... } ... }
포럼 이름을 변경할 때 다른 프로그램은 먼저 ForumProxy를 처리해야 합니다. ForumProxy는 특정 작업을 수행할 권한이 있는지 여부를 결정합니다. " 및 "보안 프록시 시스템".
일상적인 애플리케이션에서는 시스템 인증이나 보안 시스템이 항상 관련되는 것이 불가피합니다. 프록시를 의식적으로 사용하든 안 하든, 실제로는 이미 프록시를 사용하고 있습니다.
계속해서 Jive와 심도 깊은 이야기를 나눠보겠습니다. 다음은 팩토리 모드에 관한 내용입니다.
Forum을 사용하려면 ForumProxy가 필요하다는 것을 이미 알고 있습니다. Jive에서 ForumFactory를 생성하려면 일반 추상 클래스인 ForumFactory를 호출하는 것이 Singleton 메소드를 통해 구현됩니다. 여기에 사용되며(또한 디자인 패턴 중 하나) getInstance()는 ForumFactoryProxy를 반환합니다.
ForumFactory를 반환하지 않고 ForumFactory의 구현 ForumFactoryProxy를 반환하는 이유는 무엇입니까? 그 이유는 분명합니다. 포럼을 만들 수 있는 권한이 있는지 확인하려면 프록시를 사용해야 합니다.
ForumFactoryProxy에서 다음과 같은 코드를 볼 수 있습니다.
public class ForumFactoryProxy extends ForumFactory { protected ForumFactory factory; protected Authorization authorization; protected ForumPermissions permissions; public ForumFactoryProxy(Authorization authorization, ForumFactory factory,ForumPermissions permissions){ this.factory = factory; this.authorization = authorization; this.permissions = permissions; } public Forum createForum(String name, String description) throws UnauthorizedException, ForumAlreadyExistsException{ //只有系统管理者才可以创建forum if (permissions.get(ForumPermissions.SYSTEM_ADMIN)) { Forum newForum = factory.createForum(name, description); return new ForumProxy(newForum, authorization, permissions); } else { throw new UnauthorizedException(); } } }
createForum 메서드도 ForumProxy를 반환합니다. 프록시는 벽과 같습니다.
여기에는 ForumProxy와 ForumFactoryProxy라는 두 개의 프록시가 있습니다. 포럼 사용 및 포럼 생성이라는 두 가지 다른 책임을 나타냅니다. 객체를 사용하는 것과 객체를 생성하는 것이 분리되는 이유는 "캡슐화"와 "디스패치"라는 Factory 패턴을 사용하는 이유이기도 합니다. 즉, 기능은 유지 관리 및 수정이 용이하도록 가능한 한 단순해야 합니다.
Jive 포럼 시스템의 다른 게시물 작성 및 사용은 모두 포럼 아이디어를 기반으로 합니다.
위에서 프록시를 사용하여 인증 메커니즘에 액세스하는 방법에 대해 설명했으며 쓰기 중 복사라는 또 다른 최적화 방법을 사용자에게 숨길 수도 있습니다. 크고 복잡한 개체를 복사하는 것은 비용이 많이 드는 작업입니다. 복사 프로세스 중에 원본 개체가 수정되지 않으면 이러한 복사 오버헤드가 필요하지 않습니다. 이 복사 프로세스를 지연하려면 프록시를 사용하십시오.
比如:我们有一个很大的Collection,具体如hashtable,有很多客户端会并发同时访问它。其中一个特别的客户端要进行连续的数据获取,此时要求其他客户端不能再向hashtable中增加或删除 东东。
最直接的解决方案是:使用collection的lock,让这特别的客户端获得这个lock,进行连续的数据获取,然后再释放lock。
public void foFetches(Hashtable ht){ synchronized(ht){ //具体的连续数据获取动作.. } }
但是这一办法可能锁住Collection会很长时间,这段时间,其他客户端就不能访问该Collection了。
第二个解决方案是clone这个Collection,然后让连续的数据获取针对clone出来的那个Collection操作。这个方案前提是,这个Collection是可clone的,而且必须有提供深度clone的方法。Hashtable就提供了对自己的clone方法,但不是Key和value对象的clone。
public void foFetches(Hashtable ht){ Hashttable newht=(Hashtable)ht.clone(); }
问题又来了,由于是针对clone出来的对象操作,如果原来的母体被其他客户端操作修改了,那么对clone出来的对象操作就没有意义了。
最后解决方案:我们可以等其他客户端修改完成后再进行clone,也就是说,这个特别的客户端先通过调用一个叫clone的方法来进行一系列数据获取操作。但实际上没有真正的进行对象拷贝,直至有其他客户端修改了这个对象Collection。
使用Proxy实现这个方案,这就是copy-on-write操作。
Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用。
更多Java设计模式之代理模式(Proxy模式)介绍相关文章请关注PHP中文网!
相关文章: