Decorator模式有代理的味道
這是一個Decorator模式例子的簡單的三個檔案
我們先建立一個介面:
public interface Work
{
public void insert();
}
介面Work有一個具體實現:插入方形樁或圓形樁,這兩個區別對Decorator是無所謂.我們以插入方形樁為例:
public class SquarePeg implements Work{
public void insert(){
System.out.println("方形樁插入");
}
}
現在有一個應用:需要在樁打入前,挖坑,在打入後,在樁上釘木板,這些額外的功能是動態,可能隨意增加調整修改,比如,可能又需要在打樁之後釘架子(只是比喻).
那麼我們使用Decorator模式,這裡方形樁SquarePeg是decoratee(被刷油漆者),我們需要在decoratee上刷些"油漆",這些油漆就是那些額外的功能.
public class Decorator implements Work{
private Work work;
//額外增加的功能被打包在這個List中
private ArrayList others = new ArrayList();
//在構造器中使用組合new方式,引入Work物件;
public Decorator(Work work)
{
this.work=work;
others.add("挖坑");
others.add("釘木板");
}
public void insert(){
newMethod();
}
//在新方法中,我們在insert之前增加其他方法,這裡次序先後是使用者靈活指定的
public void newMethod()
{
otherMethod();
work.insert();
}
public void otherMethod()
{
ListIterator listIterator = others.listIterator();
while (listIterator.hasNext())
{
System.out.println(((String)(listIterator.next())) + " 正在進行");
}
}
}
好了,Decorator模式出來了,客戶端也的程式碼:
Work squarePeg = new SquarePeg();
Work decorator = new Decorator(squarePeg);
decorator.insert();
在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]);
}
.....
}
因此,Forum中各種操作許可權是和ForumPermissions定義的使用者級別有關係的,作為介面Forum的實現:ForumProxy正是將這種對應關係聯絡起來.比如,修改Forum的名稱,只有論壇管理者或系統管理者可以修改,程式碼如下:
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決定是否有許可權做某一樣事情,ForumProxy是個名副其實的"閘道器","安全代理系統".
在平時應用中,無可避免總要涉及到系統的授權或安全體系,不管你有無意識的使用Proxy,實際你已經在使用Proxy了.
我們繼續結合Jive談入深一點,下面要涉及到工廠模式了,如果你不瞭解工廠模式,請看我的另外一篇文章:設計模式之Factory
我們已經知道,使用Forum需要透過ForumProxy,Jive中建立一個Forum是使用Factory模式,有一個總的抽象類ForumFactory,在這個抽象類中,呼叫ForumFactory是透過getInstance()方法實現,這裡使用了Singleton(也是設計模式之一,由於介紹文章很多,我就不寫了,看這裡),getInstance()返回的是ForumFactoryProxy.
為什麼不返回ForumFactory,而返回ForumFactory的實現ForumFactoryProxy?
原因是明顯的,需要透過代理確定是否有許可權建立forum.
在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();
}
}
由上面可以找到兩個共同點為
1.兩個實現類都派生於同一個介面
2.其中一個實現類引用了另一個實現類,並作了功能的增加
我們先建立一個介面:
public interface Work
{
public void insert();
}
介面Work有一個具體實現:插入方形樁或圓形樁,這兩個區別對Decorator是無所謂.我們以插入方形樁為例:
public class SquarePeg implements Work{
public void insert(){
System.out.println("方形樁插入");
}
}
現在有一個應用:需要在樁打入前,挖坑,在打入後,在樁上釘木板,這些額外的功能是動態,可能隨意增加調整修改,比如,可能又需要在打樁之後釘架子(只是比喻).
那麼我們使用Decorator模式,這裡方形樁SquarePeg是decoratee(被刷油漆者),我們需要在decoratee上刷些"油漆",這些油漆就是那些額外的功能.
public class Decorator implements Work{
private Work work;
//額外增加的功能被打包在這個List中
private ArrayList others = new ArrayList();
//在構造器中使用組合new方式,引入Work物件;
public Decorator(Work work)
{
this.work=work;
others.add("挖坑");
others.add("釘木板");
}
public void insert(){
newMethod();
}
//在新方法中,我們在insert之前增加其他方法,這裡次序先後是使用者靈活指定的
public void newMethod()
{
otherMethod();
work.insert();
}
public void otherMethod()
{
ListIterator listIterator = others.listIterator();
while (listIterator.hasNext())
{
System.out.println(((String)(listIterator.next())) + " 正在進行");
}
}
}
好了,Decorator模式出來了,客戶端也的程式碼:
Work squarePeg = new SquarePeg();
Work decorator = new Decorator(squarePeg);
decorator.insert();
在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]);
}
.....
}
因此,Forum中各種操作許可權是和ForumPermissions定義的使用者級別有關係的,作為介面Forum的實現:ForumProxy正是將這種對應關係聯絡起來.比如,修改Forum的名稱,只有論壇管理者或系統管理者可以修改,程式碼如下:
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決定是否有許可權做某一樣事情,ForumProxy是個名副其實的"閘道器","安全代理系統".
在平時應用中,無可避免總要涉及到系統的授權或安全體系,不管你有無意識的使用Proxy,實際你已經在使用Proxy了.
我們繼續結合Jive談入深一點,下面要涉及到工廠模式了,如果你不瞭解工廠模式,請看我的另外一篇文章:設計模式之Factory
我們已經知道,使用Forum需要透過ForumProxy,Jive中建立一個Forum是使用Factory模式,有一個總的抽象類ForumFactory,在這個抽象類中,呼叫ForumFactory是透過getInstance()方法實現,這裡使用了Singleton(也是設計模式之一,由於介紹文章很多,我就不寫了,看這裡),getInstance()返回的是ForumFactoryProxy.
為什麼不返回ForumFactory,而返回ForumFactory的實現ForumFactoryProxy?
原因是明顯的,需要透過代理確定是否有許可權建立forum.
在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();
}
}
由上面可以找到兩個共同點為
1.兩個實現類都派生於同一個介面
2.其中一個實現類引用了另一個實現類,並作了功能的增加
相關文章
- Proxy模式與Decorator模式的區別模式
- 關於Decorator模式模式
- Decorator裝飾模式模式
- 裝飾模式 (Decorator Pattern)模式
- Decorator模式、BUG和AOP模式
- 裝飾器模式(Decorator)模式
- 設計模式--裝飾模式(Decorator Pattern)設計模式
- 設計模式-裝飾模式(Decorator Pattern)設計模式
- 設計模式 (十)裝飾模式(Decorator)設計模式
- 關於Adapter模式和Decorator模式APT模式
- 關於Decorator模式的幾點想法模式
- 設計模式的征途—10.裝飾(Decorator)模式設計模式
- Decorator裝飾設計模式設計模式
- “使命召喚”的新“吃雞”模式味道如何?模式
- PHP設計模式- Decorator 裝飾器模式PHP設計模式
- java設計模式-裝飾器模式(Decorator)Java設計模式
- 重構:幹掉有壞味道的程式碼
- 心得:Spring AOP和Decorator模式Spring模式
- http代理ip有哪兩種模式HTTP模式
- 設計模式之裝飾器模式(decorator pattern)設計模式
- PHP設計模式之裝飾器模式(Decorator)PHP設計模式
- C++ 設計模式 裝飾模式(Decorator Pattern)C++設計模式
- JAVA設計模式之 裝飾模式【Decorator Pattern】Java設計模式
- C#設計模式系列:裝飾模式(Decorator)C#設計模式
- 你有被代理過嗎?講講開源框架都在用的代理模式框架模式
- 轉載-Java設計模式之DecoratorJava設計模式
- 今天試了一下Decorator模式模式
- 09 結構型模式之裝飾者模式(decorator)模式
- C#設計模式-裝飾器模式(Decorator Pattern)C#設計模式
- PHP設計模式(六)—裝飾器模式(Decorator Pattern)PHP設計模式
- Java設計模式之裝飾者模式(Decorator pattern)Java設計模式
- 設計模式--裝飾器模式Decorator(結構型)設計模式
- 設計模式中的俄羅斯套娃:裝飾者(Decorator)模式設計模式
- 關於Proxy和Decorator設計模式的疑問設計模式
- 設計模式——代理模式的思考設計模式
- 代理模式模式
- 設計模式之Decorator在餐館中的應用設計模式
- 代理模式 (追女孩代理)模式