인 스 턴 스 분석 C\#디자인 모드 프로 그래 밍 에서 간단 한 공장 모드 사용

11085 단어 C#디자인 모드
단순 공장 모델 소개
간단 한 공장 하면 자 연 스 러 운 첫 번 째 의문 은 당연히 간단 한 공장 모델 이 무엇 입 니까?현실 생활 에서 공장 은 제품 생산 을 책임 지 는 것 이다.마찬가지 로 디자인 모델 에서 간단 한 공장 모델 도 우 리 는 생산 대상 을 책임 지 는 유형 으로 이해 할 수 있다.우 리 는 평소에 프로 그래 밍 에서'new'키 워드 를 사용 하여 대상 을 만 들 때 이런 유형 은 이 대상,즉 그들 과 의 결합 도가 높 고 수요 가 변화 할 때우 리 는 이러한 소스 코드 를 수정 해 야 한다.이때 우 리 는 대상(OO)을 대상 으로 하 는 매우 중요 한 원칙 으로 이 문 제 를 해결 할 수 있다.이 원칙 은 바로 포장 이 바 뀌 는 것 이다.포장 이 바 뀌 려 면 자 연 스 럽 게 변 경 된 코드 를 찾 은 다음 에 변 경 된 코드 를 클래스 로 포장 해 야 한다.이런 사고방식 은 바로 우리 의 간단 한 공장 모델 의 실현 방식 이다.다음은 현실 생활 의 예 를 통 해 간단 한 공장 모델 을 끌 어 낸다.
밖에서 아르 바 이 트 를 하 는 사람 은 밖에서 밥 을 자주 먹 는 것 을 피 할 수 없다.물론 우 리 는 집에 서 밥 을 해서 먹 을 수도 있다.그러나 스스로 밥 을 해서 번 거 롭 게 먹 어야 하기 때문이다.그러나 밥 을 먹 으 러 나 가면 이런 번 거 로 움 이 전혀 없다.우 리 는 식당 에 가서 주문 만 하면 된다.음식 을 사 는 일 은 식당 에 맡 기 면 된다.이곳 식당 은 간단 한 공장 역할 을 한다.현실 생활 의 예 를 코드 로 어떻게 표현 하 는 지 살 펴 보 자.
예시
스스로 요리 하 는 경우:

/// <summary>
  ///        
  ///         ,             
  /// </summary>
  public class Customer
  {
    /// <summary>
    ///     
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static Food Cook(string type)
    {
      Food food = null;
      //   A :           ?
      //   B :       
      //   A :   ,      
      if (type.Equals("     "))
      {
        food = new TomatoScrambledEggs();
      }
      //         ,         
      //          ,           ?
      else if (type.Equals("    "))
      {
        food = new ShreddedPorkWithPotatoes();
      }
      return food;
    }
    static void Main(string[] args)
    {
      //       
      Food food1 = Cook("     ");
      food1.Print();
      Food food2 = Cook("    ");
      food1.Print();
      Console.Read();
    }
  }
 /// <summary>
  ///     
  /// </summary>
  public abstract class Food
  {
    //        
    public abstract void Print();
  }
  /// <summary>
  ///          
  /// </summary>
  public class TomatoScrambledEggs : Food
  {
    public override void Print()
    {
      Console.WriteLine("       !");
    }
  }
  /// <summary>
  ///        
  /// </summary>
  public class ShreddedPorkWithPotatoes : Food
  {
    public override void Print()
    {
      Console.WriteLine("      ");
    }
  }
스스로 밥 을 짓 는 다.만약 에 우리 가 다른 요 리 를 먹고 싶 을 때 이런 요 리 를 사 는 것 과 채 소 를 씻 는 번 거 로 운 조작 이 필요 하 다.식당(즉 간단 한 공장)이 생기 면 우 리 는 이런 조작 을 식당 에 맡 길 수 있다.이때 소비자(즉 우리)가 요리(즉 구체 적 인 대상)에 대한 의존 관 계 는 직접적 으로 간접 적 으로 바 뀌 었 다.이렇게 하면 대상 을 대상 으로 하 는 또 다른 원칙 인 대상 간 의 결합 도 를 낮 추 는 것 이다.다음은 식당 이 생 긴 후의 실현 코드(즉 간단 한 공장 의 실현)를 구체 적 으로 살 펴 보 자.

/// <summary>
  ///        ,             
  ///      ,  (       )    (     )
  /// </summary>
  class Customer
  {
    static void Main(string[] args)
    {
      //               
      Food food1 = FoodSimpleFactory.CreateFood("     ");
      food1.Print();
      //           
      Food food2 = FoodSimpleFactory.CreateFood("    ");
      food2.Print();
      Console.Read();
    }
  }
  /// <summary>
  ///     
  /// </summary>
  public abstract class Food
  {
    //        
    public abstract void Print();
  }
  /// <summary>
  ///          
  /// </summary>
  public class TomatoScrambledEggs : Food
  {
    public override void Print()
    {
      Console.WriteLine("       !");
    }
  }
  /// <summary>
  ///        
  /// </summary>
  public class ShreddedPorkWithPotatoes : Food
  {
    public override void Print()
    {
      Console.WriteLine("      ");
    }
  }
  /// <summary>
  ///      ,      
  /// </summary>
  public class FoodSimpleFactory
  {
    public static Food CreateFood(string type)
    {
      Food food = null;
      if (type.Equals("    "))
      {
        food= new ShreddedPorkWithPotatoes();
      }
      else if (type.Equals("     "))
      {
        food= new TomatoScrambledEggs();
      }
      return food;
    }
  }

그 밖 에 간단 한 공장 모델 을 반사 적 으로 실현 하 는 예 도 있다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
  public interface IFruit
  {
  }

  public class Orange : IFruit
  {
    public Orange()
    {
      Console.WriteLine("An orange is got!");
    }
  }

  public class Apple : IFruit
  {
    public Apple()
    {
      Console.WriteLine("An apple is got!");
    }
  }

  public class FruitFactory
  {
    private static FruitFactory _instance = new FruitFactory();
    public static FruitFactory Instance
    {
      get { return _instance; }
    }

    public IFruit MakeFruit(string Name)
    {
      IFruit MyFruit = null;
      try
      {
        Type type = Type.GetType(Name, true);
        MyFruit = (IFruit)Activator.CreateInstance(type);
      }
      catch (TypeLoadException e)
      {
        Console.WriteLine("I dont know this kind of fruit,exception caught - {0}", e.Message);
      }
      return MyFruit;
    }
  }

  public class Test
  {
    static void Main()
    {
      string FruitName = Console.ReadLine();
      FruitFactory.Instance.MakeFruit("ConsoleApplication1." + FruitName);
    }
  }
}

장점 과 단점
간단 한 공장 모델 의 실현 을 본 후에 당신 과 당신 의 동료 들 은 이런 의문 을 가지 게 될 것 입 니 다.(내 가 공부 할 때 도 있 기 때 문 입 니 다)그러면 우 리 는 공장 류 로 변 화 를 옮 겼 을 뿐 변화 가 없 는 것 같 습 니 다.고객 이 다른 요 리 를 먹고 싶 을 때 우 리 는 공장 류 의 방법(즉,케이스 문 구 를 많이 추가 하 는 것 입 니 다.단순 공장 모델 을 적용 하지 않 기 전에 고객 류 를 수정 했다.내 가 먼저 말 하고 자 하 는 것 은 당신 과 당신 의 동료 가 매우 옳 습 니 다.이것 이 바로 간단 한 공장 모델 의 단점 입 니 다.(이 단점 뒤에 소 개 된 공장 방법 은 잘 해결 할 수 있 습 니 다)그러나 간단 한 공장 모델 과 이전의 실현 에 도 장점 이 있 습 니 다.
간단 한 공장 모델 은 클 라 이언 트 가 구체 적 인 대상 에 직접 의존 하 는 문 제 를 해결 하고 클 라 이언 트 는 대상 을 직접 만 드 는 책임 을 없 앨 수 있 으 며 제품 만 소비 할 수 있다.간단 한 공장 모델 이 책임 에 대한 분할 을 실현 하 였 다.
간단 한 공장 모델 도 코드 를 재 활용 하 는 역할 을 했다.예전 의 실현(자신 이 밥 을 하 는 상황)에서 한 사람 이 똑 같이 자신의 유형 에서 요 리 를 하 는 방법 을 바 꾸 었 기 때문이다.그리고 간단 한 공장 이 생 긴 후에 식당 에 가서 밥 을 먹 는 모든 사람들 이 그렇게 귀 찮 지 않 고 소 비 를 책임 지면 된다.이때 간단 한 공장 의 요리 방법 은 모든 고객 을 공용 하 게 했다.또한 이 점 은 간단 한 공장 방법의 단점 이기 도 합 니 다.공장 류 는 모든 제품 의 건설 논 리 를 집중 시 켰 기 때문에 정상적으로 일 하지 못 하면 전체 시스템 이 영향 을 받 고 이해 하기 어 려 운 것 도 없습니다.사물 이 양면성 이 있 는 것 처럼 일리 가 있 습 니 다)
위 에서 간단 한 공장 모델 의 단점 을 소 개 했 지만 다음은 간단 한 공장 모델 의 단점 을 요약 한다.
공장 류 는 모든 제품 의 창설 논리 에 집중 되 어 정상적으로 일 하지 못 하면 시스템 전체 가 영향 을 받는다.
시스템 확장 이 어려워 신제품 을 추가 하면 공장 논 리 를 수정 해 야 하기 때문에 공장 논리 가 너무 복잡 하 다.
간단 한 공장 모델 이후 의 장단 점 을 알 게 된 후에 우 리 는 간단 한 공장 의 응용 장면 을 알 수 있다.
공장 류 가 창설 을 담당 하 는 대상 이 비교적 적 을 때 간단 한 공장 모드 사용 을 고려 할 수 있다()
고객 이 공장 류 에 들 어 오 는 매개 변수 만 알 고 있다 면 대상 을 어떻게 만 드 는 지 에 대한 논리 에 관심 이 없 을 때 간단 한 공장 모델 을 사용 하 는 것 을 고려 할 수 있다.
단순 공장 모드 UML 그림
간단 한 공장 모델 은 정적 방법 모델 이 라 고도 부른다.간단 한 공장 모델 의 UML 그림 은 다음 과 같다.
2016217120401719.png (934×349)
.NET 에서 간단 한 공장 모델 의 실현
간단 한 공장 모델 을 소개 한 후에 저 는.NET 라 이브 러 리 에서 간단 한 공장 모델 을 실현 한 유형 이 있 습 니까?뒤에 확실히 있 습 니 다..NET 에서 System.Text.Encoding 류 는 간단 한 공장 모델 을 실 현 했 습 니 다.이 유형의 GetEncoding(int codepage)은 공장 방법 입 니 다.구체 적 인 코드 는 Reflector 역 컴 파일 도 구 를 통 해 볼 수 있 습 니 다.아래 에 저도 이 방법의 일부 코드 를 붙 입 니 다.

public static Encoding GetEncoding(int codepage)
{
  Encoding unicode = null;
  if (encodings != null)
  {
    unicode = (Encoding) encodings[codepage];
  }
  if (unicode == null)
  {
    object obj2;
    bool lockTaken = false;
    try
    {
      Monitor.Enter(obj2 = InternalSyncObject, ref lockTaken);
      if (encodings == null)
      {
        encodings = new Hashtable();
      }
      unicode = (Encoding) encodings[codepage];
      if (unicode != null)
      {
        return unicode;
      }
      switch (codepage)
      {
        case 0:
          unicode = Default;
          break;
        case 1:
        case 2:
        case 3:
        case 0x2a:
          throw new ArgumentException(Environment.GetResourceString("Argument_CodepageNotSupported", new object[] { codepage }), "codepage");
        case 0x4b0:
          unicode = Unicode;
          break;
        case 0x4b1:
          unicode = BigEndianUnicode;
          break;
        case 0x6faf:
          unicode = Latin1;
          break;
        case 0xfde9:
          unicode = UTF8;
          break;
        case 0x4e4:
          unicode = new SBCSCodePageEncoding(codepage);
          break;
        case 0x4e9f:
          unicode = ASCII;
          break;
        default:
          unicode = GetEncodingCodePage(codepage);
          if (unicode == null)
          {
            unicode = GetEncodingRare(codepage);
          }
          break;
      }
      encodings.Add(codepage, unicode);
      return unicode;
    }
}

.NET 에서 Encoding 의 UML 그림 은 다음 과 같 습 니 다.
2016217120425194.png (786×271)
Encoding 류 에서 실 현 된 간단 한 공장 모델 은 간단 한 공장 모델 의 변화 이다.이때 간단 한 공장 류 는 추상 적 인 제품 역할 을 하지만.NET 에서 Encoding 류 는 간단 한 공장 모델 에 존재 하 는 문제점 을 어떻게 해결 합 니까?(즉,인 코딩 을 새로 추가 하면 어떻게 합 니까?)GetEncoding 방법 에 있 는 switch 함 수 는 다음 과 같은 코드 가 있 습 니 다.

switch (codepage)
   {
     .......
  default:
          unicode = GetEncodingCodePage(codepage);
          if (unicode == null)
          {
            unicode = GetEncodingRare(codepage); //       
          }
          break;
      ......
   }
GetEncoding Rare 방법 에는 자주 사용 되 지 않 는 인 코딩 의 실례 화 코드 가 있 는데 마이크로 소프트 는 이 방법 을 통 해 새로운 인 코딩 문 제 를 정식으로 해결한다.(사실은 가능 한 모든 인 코딩 상황 을 보 여 주 는 것 이다)마이크로소프트 가 이런 방식 으로 이 문 제 를 해결 하 는 이 유 는 현재 인 코딩 이 안정 되 었 고 새로운 인 코딩 을 추가 할 가능성 이 비교적 낮 기 때문에.NET 4.5 에서 이 부분 코드 를 변경 하지 않 았 기 때문이다.

좋은 웹페이지 즐겨찾기