잊지 않겠습니다.

최소 지식 원칙

Book 2009. 1. 7. 11:56

최소 지식 원칙에서의 가이드라인

1. 객체 자체만의 호출

2. 메소드에서 매개 변수로 전달된 객체

3. 그 메소드에서 생성하거나 인스턴스를 만든 객체

4. 그 객체에 속하는 구성 요소

  

public static double GetTemplrature()

{

  // NOTE : 틀린 경우

  Thermoeter thermometer = station.GetThermometer();

  return thermometer.GetTemperature();

}


public static double GetTemperature()

{

  //NOTE : 맞는 경우 

  return station.GetTemperature();

 } 

Posted by Y2K
,

구상되는 기본틀은 모두 Template를 이용하고, Template에서 이용되는 method들을 따로 객체화 시킨다.

  

namespace TemplatePattern

{

  public abstract class SYNCmailBasePannel

  {

    public abstract void LoadPannel();

    public abstract void MoveNextPannel();

    public abstract void MovePreviousPannel();


    public void ArrangeSubControls()

    {

      //NOTE : arrange sub controls

    }


    public void PaintPanel()

    {

      //NOTE : paint panel

    }

  }


  #region Using Strategy Pattern

  public interface ILoginService

  {

    bool Login(string logonName, string password);

  }


  public interface IChangeDisplayName

  {

    bool ChangeDisplayName(string displayName);

  }

   

  public class SYNCmailLoginService : ILoginService

  {


    #region ILoginService Members


    public bool Login(string logonName, string password)

    {

      throw new NotImplementedException();

    }


    #endregion

  }


  public class SYNCmailChangeDisplayNamer : IChangeDisplayName

  {

    #region IChangeDisplayName Members


    public bool ChangeDisplayName(string displayName)

    {

      throw new NotImplementedException();

    }


    #endregion

  }


  #endregion


  public class SYNCmailDisplayPannel : SYNCmailBasePannel

  {

    public IChangeDisplayName iChangeDisplayName;


    public override void LoadPannel()

    {

      throw new NotImplementedException();

    }


    public override void MoveNextPannel()

    {

      iChangeDisplayName.ChangeDisplayName("newDisplayName");

    }


    public override void MovePreviousPannel()

    {

      throw new NotImplementedException();

    }

  }


  public class SYNCmailLoginPannel : SYNCmailBasePannel

  {

    public ILoginService iLoginService;


    public override void LoadPannel()

    {

      //TODO : GET Login information

    }


    public override void MoveNextPannel()

    {

      //TODO :

      // 1. Connection SYNCmail API

      // 2. Check Login Informations

      if ( iLoginService.Login("logonName", "password") )

      {

        //NOTE : Move Next Pannel

      }

    }


    public override void MovePreviousPannel()

    {

      //TODO :

      // Move previous Pannel

    }

  }

}

Posted by Y2K
,

Collection 구현 방법을 노출하지 않으면서 Collection 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법의 제공

  

항목들에 대한 반복 작업을 일괄적으로 할 수 있도록 해준다.

  

.NET Framework :

System.Collections.IEnumerable  : GetEnumerator()를 통해서 IEnumerator를 얻어낸다.

System.Collections.IEnumerator : 객체에 대한 접근 항목을 보여주는 interface. Current, MoveNext, Reset을 통해서 모든 객체에 대한 일괄적인 접근제어를 한다. 

  

  public class DinnerMenus2 : IEnumerable

  {

    #region IEnumerable Members


    public IEnumerator GetEnumerator()

    {

      throw new NotImplementedException();

    }


    #endregion

  }



  public class DinnerMenus : IEnumerator

  {

    private int position;


    public DinnerMenus()

    {

      position = 0;

    }


    #region IEnumerator Members


    public object Current

    {

      get { throw new NotImplementedException(); }

    }


    public bool MoveNext()

    {

      throw new NotImplementedException();

    }


    public void Reset()

    {

      throw new NotImplementedException();

    }


    #endregion

  }

Posted by Y2K
,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StrategyPattern
{
  /// <summary>
  /// Strategy pattern을 이용. : SYNCmail Mobile도 같은 방법으로 구현해보는 것이 어떨까 고민되고 있음.
  /// </summary>
  public abstract class OperationPanel
  {
    public IOperation Operation { get; set; }
    public void DoOperation()
    {
      Operation.DoMainOperation();
    }
  }

  public interface IOperation
  {
    void DoMainOperation();
    void DoSubOperation();
    void LoadOperation();
  }

  public class CheckPasswordOperation : IOperation
  {
    public string LogonName { get; set; }
    public string Password { get; set; }

    public void DoMainOperation()
    {
      Console.WriteLine("Check Password");
    }

    public void DoSubOperation()
    {
      Console.WriteLine("Cancel operation");
    }

    public void LoadOperation()
    {
      Console.WriteLine("Display");
    }
  }
  //abstract class의 이용을 하지 않고, Interface의 구현 및 조합을 통해서, 각각의 class의 구현을 행한다.
  //abstract method를 사용하지 않고, abstract method에서 사용되는 동작의 정의를 Interface를 통한다. 그 interface의 구현을 통해서 만들어주는 패턴

}
Posted by Y2K
,

개인적으로 가장 많이 사용한 패턴.

DB에 대한 connection 문제 해결이라던지, 하나의 리소스를 사용하는 방법으로 주로 사용한다.

특히 윈도우에서는 Registery의 참조부분을 행할때 주로 사용하게 된다.

  

.NET에서 keyword인 volatile를 사용한 것을 주목할것.

  

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;


namespace SingletonPattern

{

  public class SingletonData

  {

    private static volatile SingletonData singletonInstance;


    public static SingletonData GetInstance()

    {

      if ( singletonInstance == null )

      {

        singletonInstance = new SingletonData();

      }

      return singletonInstance;

    }


    private SingletonData()

    {

    }

  }

}

Posted by Y2K
,
using System;
using System.Collections.Generic;

namespace ObserverPattern
{
  public interface IObserver
  {
    void Update(float temp, float humidity, float pressure);
  }

  public interface ISubject
  {
    void RegisterObserver(IObserver o);
    void RemoveObserver(IObserver o);
    void NotifyObservers();
  }

  public interface IDisplayElement
  {
    void Display();
  }


  public class WeatherSubject : ISubject
  {
    readonly List<IObserver> observers;
    float temperature;
    float pressure;
    float humidity;

    public void GetterMeasurements(float inTemperature, float inHumidity, float inPressure)
    {
      temperature = inTemperature;
      humidity = inHumidity;
      pressure = inPressure;
      NotifyObservers();
    }

    public WeatherSubject()
    {
      observers = new List<IObserver>();
    }
    #region ISubject Members

    public void RegisterObserver(IObserver o)
    {
      observers.Add(o);
    }

    public void RemoveObserver(IObserver o)
    {
      observers.Remove(o);
    }

    public void NotifyObservers()
    {
      foreach ( IObserver observer in observers )
      {
        observer.Update(temperature, humidity, pressure);
      }
    }

    #endregion
  }
}
Posted by Y2K
,

object의 생성부분을 처리하는 class를 factory로 한다. 

특정한 객체를 만들어서 넘겨줄때, 또는 객체를 생성하고, 준비하는 과정에 대한 기본적인 내용이 필요한 경우에 Factory를 만들어서 Factory에서 처리하도록 한다. 


 

using System;


namespace FactoryPattern1

{

  public interface IPizzaStore

  {

    Pizza OrderPizza(string pizzaName);

  }


  public interface IPizzaFactory

  {

    Pizza CreatePizza(string pizzaName);

  }


  public class MyHomePizzaFactory : IPizzaFactory

  {

    #region IPizzaFactory Members


    public Pizza CreatePizza(string pizzaName)

    {

      return new Pizza() { Name = pizzaName + " Sweet MyHome" };

    }


    #endregion

  }


  public class MyHomePizzaStore : PizzaStore, IPizzaStore

  {

    IPizzaFactory pizzaFactory;

    public MyHomePizzaStore(IPizzaFactory pizzaFactory)

    {

      this.pizzaFactory = pizzaFactory;

    }


    #region IPizzaStore Members


    public Pizza OrderPizza(string pizzaName)

    {

      Pizza pizza = pizzaFactory.CreatePizza(pizzaName);

      PreparePizza(pizza);

      CutPizza(pizza);


      //this method is changable : in my home, we eat pizza with no boxing.


      return pizza;

    }


    #endregion

  }


  public class HostwayPizzaFactory : IPizzaFactory

  {


    #region IPizzaFactory Members


    public Pizza CreatePizza(string pizzaName)

    {

      return new Pizza() { Name = pizzaName + " HostwayPizza" };

    }


    #endregion

  }

  public class HostwayPizzaStore : PizzaStore, IPizzaStore

  {

    IPizzaFactory pizzaFactory;


    public HostwayPizzaStore(IPizzaFactory pizzaFactory)

    {

      this.pizzaFactory = pizzaFactory;

    }


    #region IPizzaStore Members


    public Pizza OrderPizza(string pizzaName)

    {

      Pizza pizza = pizzaFactory.CreatePizza(pizzaName);

      PreparePizza(pizza);

      CutPizza(pizza);

      BoxingPizza(pizza);

      return pizza;

    }


    #endregion

  }


  public abstract class PizzaStore

  {

    public string CutPizza(Pizza pizza)

    {

      return "Cutting Pizza";

    }


    public string PreparePizza(Pizza pizza)

    {

      return "Prepare Pizza";

    }


    public string BoxingPizza(Pizza pizza)

    {

      return "Boxing pizza";

    }

  }


  public class Pizza

  {

    public string Name { get; set; }

  }

}

Posted by Y2K
,

복잡한 여러개의 Interface를 단순화하기 위한 Pattern.

하나이상의 Class의 복잡한 interface를 단순한 Facade로 덮어주는 Pattern.

  

용도에 따른 변경에 주안점을 주게 된다 : 하나의 복잡한 일을 하는 것에 대한 쉬운 접근 방법의 제공 

단순화된 인터페이스를 제공하면서도, 클라이언트에서 필요로 한다면 sub class의 모든 기능을 제공할 수 있어야지 된다. 

  

  

  public interface IHomeTheaterFacade

  {

    void TurnOnMovie();

    void TurnOffMovie();

  }


  public class HomeTheaterFacade : IHomeTheaterFacade

  {

    object amp;

    object tuner;

    object dvdPlayer;

    object dvd;

    object projector;

    object screen;


    public HomeTheaterFacade(object amp, object tuner, object dvdPlayer, object dvd, object projector, object screen)

    {

      this.amp = amp;

      this.tuner = tuner;

      this.dvdPlayer = dvdPlayer;

      this.dvd = dvd;

      this.projector = projector;

      this.screen = screen;

    }


    #region IHomeTheaterFacade Members


    public void TurnOnMovie()

    {

      //Note : Do some thing      

    }


    public void TurnOffMovie()

    {

      //Note : Do some thing

    }


    #endregion

  } 

Posted by Y2K
,

Decorator pattern에서는 객체에 추가적인 요소를 동적으로 첨가하는 것이 목적이다. 

하나의 class에서 다른 class로 확장되어서 나가는 하나의 그림에서 다른 그림으로 확장되어 나가는 방법을 제시할 수 있으면 된다.

  

Decorator Pattern의 주안점은 생성자이다. 생성자에서 자신이 상속받은 interface를 인자로 받아서, 전의 객체에 장식(decorator)를 해주는 것이 최선의 방법이 된다. 

  

using System;

namespace DecoratorPattern

{

  public class Program

  {

    public static void Main()

    {

      Photo photo1 = new Photo();    //With Frame photo

      Photo photo2 = new Photo();    //With Stamp & Frame Photo


      PhotoFrame photoFrame = new PhotoFrame(photo1);

       

      PhotoFrame photoFrame2 = new PhotoFrame(photo2);

      PhotoStamp photoStamp = new PhotoStamp(photoFrame2);


      Console.WriteLine(photoFrame.Display());

      Console.WriteLine(photoStamp.Display());


      Console.ReadLine();

    }

  }

   

  public interface IPhoto

  {

    string Display();

    string Print();

  }

   

  public class Photo : IPhoto

  {

    #region IPhoto Members

    public string Display()

    {

      return "Display Photo";

    }


    public string Print()

    {

      return "Print Photo";

    }


    #endregion

  }


  /// <summary>

  /// Photo with a Frame.

  /// </summary>

  public class PhotoFrame : IPhoto

  {

    readonly IPhoto originalPhoto;


    public PhotoFrame(IPhoto originalPhoto)

    {

      this.originalPhoto = originalPhoto;

    }


    #region IPhoto Members


    public string Display()

    {

      return originalPhoto.Display() + " with Frame";

    }


    public string Print()

    {

      return originalPhoto.Print() + " with Frame";

    }


    #endregion

  }


  public class PhotoStamp : IPhoto

  {

    readonly IPhoto photo;


    public PhotoStamp(IPhoto photo)

    {

      this.photo = photo;

    }


    #region IPhoto Members


    public string Display()

    {

      return photo.Display() + " with Stamp.";

    }


    public string Print()

    {

      return photo.Print() + " with Stamp";

    }

    #endregion

  }

}

Posted by Y2K
,

하나의 옛날 Interface에서 새로운 Interface로의 전환이 이루어지고, 지원되지 않는 interface가 존재하게 될때에. 

  

  public interface IEnumerationExam

  {

    bool HasMoreElements();

    void NextElement();

  }


  public interface IIterator

  {

    bool HasNext();

    void Next();

    void Remove();

  }


  public class EnemurationIterator : IIterator

  {

    private IEnumerationExam iEnumerationExam;

    #region IIterator Members


    public bool HasNext()

    {

      return iEnumerationExam.HasMoreElements();

    }


    public void Next()

    {

      iEnumerationExam.NextElement();

    }


    public void Remove()

    {

      throw new NotSupportedException();

    }


    #endregion

  }

Posted by Y2K
,