14. 보호용 프락시 구현

14. 4 구현

프락시 패턴 중에 보호용 프락시에 대한 예제 프로그램을 구현하는 순서는 IView와 Picture, 보호용 프락시인 ProctectionPicture, PictureManager와 데모 코드 순으로 하겠습니다.

14.4.1 IView와Picture

IView에서는 정보를 보여주는 메서드와 소유자를 얻어오는 속성에 대한 약속할게요. 이를 구현 약속하는Picture와 ProtectionPicture에서는 약속한 기능을 구현해야 하겠죠.

Picture의 생성자 메서드에서는 사진 이름과 소유자 정보를 입력 인자로 받도록 할게요. 그리고, View 메서드에서는 이들 정보를 보여주게 하고 소유자 정보를 얻어오는 속성을 제공해야 합니다.

 ▶ IView.cs

namespace ProtectionProxy
{
    interface IView
    {
        void View();
        string Owner
        {
            get;
        }
    }
}

 ▶ Picture.cs

using System;
namespace ProtectionProxy
{
    class Picture:IView
    {
        string name;
        public string Owner
        {
            get;
            private set;
        }
        public Picture(string name,string owner)
        {
            this.name = name;
            Owner = owner;
        }
        public void View()
        {
            Console.WriteLine("파일명:{0} 소유자:{1}",name,Owner);
        }
    }
}

14.4.2 ProtectionPicture

보호용 프락시인 ProtectionPicture도 실제 개체인 사진과 일관적으로 사용할 수 있게 IView 인터페이스를 구현 약속하기로 하였습니다.

보호용 프락시의 생성자 메서드에서는 입력 인자로 전달받은 사진 이름과 소유자 정보를 기반으로 사진 개체를 생성합니다. 이와 같이 설정을 함으로써 사진의 정보를 보여주는 메서드나 소유자 정보를 얻어오는 속성을 구현함에 있어 내부에 있는 실제 개체를 이용할 수 있습니다.

보호용 프락시의 경우 권한에 따라 실제 개체의 특정 행위를 사용하는 것을 막을 수 있어야 하기 때문에 여기에서는 사용자를 설정하는 메서드와 사진을 사용할 수 있는 사용자를 추가할 수 있는 기능을 추가로 제공할게요.

이와 같은 설정은 사진 정보를 보여주는 메서드에서 사용 권한이 부여된 사용자가 아닌 경우에는 실제 개체의 정보를 보여주는 것을 막을 수 있게 해 줍니다.

 ▶ ProctectionPicture.cs 

using System;
using System.Collections.Generic;
namespace ProtectionProxy
{
    class ProtectionPicture:IView
    {
        Picture picture = null;
        string user = string.Empty;
        List<string> available_users = new List<string>();
        public ProtectionPicture(string name,string owner)
        {
            picture = new Picture(name,owner);
        }
        public void View()
        {
            if(IsAvailableUser(user))
            {
                picture.View();
            }
            else
            {
                Console.WriteLine("사진을 볼 수 있는 권한이 없습니다.");
            }
        }


        public string Owner
        {
            get
            {
                return picture.Owner;
            }
        }
         private bool IsAvailableUser(string user)
        {
            if(picture.Owner == user)
            {
                return true;
            }
            foreach(string name in available_users)
            {
                if(name == user)
                {
                    return true;
                }
            }
            return false;
        }        
        public void AddAvailableUser(string owner,string user)
        {
            if(owner != Owner)
            {
                Console.WriteLine("소유자만이 사용 권한 설정을 할 수 있습니다.");
                return;
            }
            if(IsAvailableUser(user)==false)
            {
                available_users.Add(user);
            }
        }        
        public void SetUser(string user)
        {
            this.user = user;
        }
    }
}

14.4.3 PictureManager와 데모 코드

사진 관리자에서는 IView 인터페이스 형식 개체를 보관할 수 있는 컬렉션을 멤버 필드로 갖고 있습니다. 사용자는 로그 인을 수행한 후에 사진을 추가하거나 전체 사진 목록을 볼 수 있게 할 것입니다. 그리고, 사용이 끝나면 로그 아웃을 수행할 수 있습니다. 사용자는 두 가지 방법으로 사진을 추가할 수 있는데 첫 번째 방법은 일반 사진을 추가하는 것이고 두 번째 방법은 보호용 사진을 추가하는 것입니다. 보호용 사진을 추가할 때에는 사진을 볼 수 있는 사용자 리스트를 입력 인자로 전달하게 할 것입니다.

  ▶ PictureManager.cs 

using System;
using System.Collections.Generic;
namespace ProtectionProxy
{
    class PictureManager
    {
        List<IView> pictures = new List<IView>();
        string login_user = string.Empty;
        public void Login(string user)
        {
            login_user = user;
            Console.WriteLine("{0} 님께서 로긴 하였습니다.",login_user);
        }
        public void MakePicture(string name)
        {
            if(login_user != string.Empty)
            {
                pictures.Add(new Picture(name,login_user));
            }
        }        
        public void MakePicture(string name,List<string> available_users)
        {
            if(login_user != string.Empty)
            {
                ProtectionPicture  pro_picture = 
                    MakeProtectionPicture(name,available_users);
                pictures.Add(pro_picture);
            }
        }


        public void ListPicture()
        {
            ProtectionPicture pp=null;
            foreach(IView ivew in pictures)
            {
                pp = ivew as ProtectionPicture;
                if(pp != null)
                {
                    pp.SetUser(login_user);
                }
                ivew.View();
            }
        }
        public void Logout()
        {
            Console.WriteLine("{0}님께서 로그 아웃 하였습니다.",login_user);
            login_user = string.Empty;
        }
        ProtectionPicture MakeProtectionPicture(string name,List<string> available_users)
        {
            ProtectionPicture  pro_picture = new ProtectionPicture(name,login_user);
            foreach(string uname in available_users)
            {
                pro_picture.AddAvailableUser(login_user,uname);
            }
            return pro_picture;
        }
    }
}

데모 코드에서는 한 명의 사용자가 로그 인을 하여 일반 사진과 보호용 사진을 추가를 한 후에 다른 사용자가 로그 인을 하여 사진을 보려고 하면 일반 사진과 권한이 있는 보호용 사진만 볼 수 있다는 것을 보여주는 코드를 작성하려고 합니다.

  ▶ Program.cs 

using System.Collections.Generic;
namespace ProtectionProxy
{
    class Program
    {
        static void Main(string[] args)
        {
            PictureManager pm = new PictureManager();
            List<string> avail_users = new List<string>();
            pm.Login("홍길동");
            pm.MakePicture("홍길동A", avail_users);
            avail_users.Add("강감찬");
            pm.MakePicture("홍길동B", avail_users);
            pm.MakePicture("홍길동C");
            pm.ListPicture();
            pm.Logout();
            pm.Login("강감찬");
            pm.ListPicture();
            pm.Logout();
        }
    }
}

다음은 보호용 프락시에 대한 예제 프로그램을 실행하였을 때의 화면입니다.

[그림] 보호용 프록시 실행 화면
[그림] 보호용 프록시 실행 화면