1. 程式人生 > 其它 >設計模式之:代理模式ProxyPattern的實現

設計模式之:代理模式ProxyPattern的實現

代理模式的理解:

  • 當用戶無法或不能直接訪問某個物件時,可以通過一個代理來間接訪問;
  • 為保證客戶端使用的透明性,所訪問的真是物件和代理物件需要實現相同的介面;
  • 代理模式分為:保護代理(Protect Proxy)、遠端代理(Remote Proxy)、虛擬代理(Virtual Proxy)、緩衝代理(Cache Proxy)、智慧引用代理(Smart Reference Proxy);
  • 本例屬於保護代理(Protect Proxy),用於控制對一個物件的訪問,給不同的使用者提供不同的訪問許可權;

類圖 with StarUML

搜尋引擎介面

    internal interface Seacher
    {
        string DoSearch(string userId,string keyword);
    }

搜尋引擎真正的實現類

    internal class RealSeacher : Seacher
    {
        public string DoSearch(string userId, string keyword)
        {
            Console.WriteLine($"使用者[{userId}]使用關鍵詞[{keyword}]查詢資訊");
            return $"關鍵詞[{keyword}]的查詢結果:\n古墓派最上乘的武功,亦是金庸武俠小說中最絕頂的武功之一。\n是祖師林朝英創來專門用來剋制全真派的武功,修練時須得二人同練,互為臂助。\n修練的第一步是先練成古墓派本門各項武功。\n第二步是學全真派武功。\n第三步再練剋制全真派武功的玉女心經。\n其境界已達到九陰真經的境界,亦即是無上的境界。";
        }
    }

搜尋引擎代理類

    internal class ProxySeacher:Seacher
    {
        private RealSeacher seacher = new RealSeacher();
        private AccessValidator validator ;
        private Logger logger ;

        public string DoSearch(string userId, string keyword)
        {
            if (this.Validate(userId))
            {
                string result = seacher.DoSearch(userId, keyword);
                this.Log(userId);
                return result;
            }
            else
            {
                return null;
            }
        }
        public bool Validate(string userId)
        {
            validator = new AccessValidator();
            return validator.Validate(userId);
        }
        public void Log(string userId)
        {
            logger = new Logger();
            logger.Log(userId);
        }
    }

登入驗證類

    internal class AccessValidator
    {
        public bool Validate(string userId)
        {
            Console.WriteLine($"在資料庫中驗證使用者[{userId}]是否合法?");
            if (userId.Equals("楊過"))
            {
                Console.WriteLine($"[{userId}]登入成功!");
                return true;
            }
            else
            {
                Console.WriteLine($"[{userId}]登入失敗!");
                return false;
            }
        }
    }

日誌列印類

    internal class Logger
    {
        public void Log(string userId)
        {
            Console.WriteLine($"使用者[{userId}]查詢次數加1...");
        }
    }

配置檔案

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<appSettings>
		<add key="proxy" value ="ProxyPattern.ProxySeacher"/>
	</appSettings>
</configuration>

客戶端類

    internal class Program
    {
        static void Main(string[] args)
        {
            //讀取配置檔案
            string proxy = ConfigurationManager.AppSettings["proxy"];
            //通過反射建立代理
            Seacher seacher = Assembly.Load("ProxyPattern").CreateInstance(proxy) as Seacher;

            string result = seacher.DoSearch("楊過","玉女心經");
            Console.WriteLine(result);
            Console.Read();
        }
    }

執行結果