인 스 턴 스 분석 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 그림 은 다음 과 같다.
.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 그림 은 다음 과 같 습 니 다.Encoding 류 에서 실 현 된 간단 한 공장 모델 은 간단 한 공장 모델 의 변화 이다.이때 간단 한 공장 류 는 추상 적 인 제품 역할 을 하지만.NET 에서 Encoding 류 는 간단 한 공장 모델 에 존재 하 는 문제점 을 어떻게 해결 합 니까?(즉,인 코딩 을 새로 추가 하면 어떻게 합 니까?)GetEncoding 방법 에 있 는 switch 함 수 는 다음 과 같은 코드 가 있 습 니 다.
switch (codepage)
{
.......
default:
unicode = GetEncodingCodePage(codepage);
if (unicode == null)
{
unicode = GetEncodingRare(codepage); //
}
break;
......
}
GetEncoding Rare 방법 에는 자주 사용 되 지 않 는 인 코딩 의 실례 화 코드 가 있 는데 마이크로 소프트 는 이 방법 을 통 해 새로운 인 코딩 문 제 를 정식으로 해결한다.(사실은 가능 한 모든 인 코딩 상황 을 보 여 주 는 것 이다)마이크로소프트 가 이런 방식 으로 이 문 제 를 해결 하 는 이 유 는 현재 인 코딩 이 안정 되 었 고 새로운 인 코딩 을 추가 할 가능성 이 비교적 낮 기 때문에.NET 4.5 에서 이 부분 코드 를 변경 하지 않 았 기 때문이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.