안녕하세요. 언제나휴일입니다.
이번에는 WaferLine 클래스를 정의하는 실습입니다.
1. WaferLine 클래스 정의
WaferLine은 Wafer를 코팅하는 생산라인을 구현할 클래스입니다.
최종적으로 WaferLineLib.dll에 정의할 형식으로 public 접근 지정할게요.
public class WaferLine { }
Wafer 코팅 공장에는 여러 개의 WaferLine이 있을 수 있을 거예요.
여기에서는 WaferLine을 구분하기 위한 일련 번호를 캡슐화할게요.
public int No { get; }
생산 라인에 코팅할 때의 회전 속도와 코팅 액이 떨어지는 속도를 캡슐화합시다.
public int Spin { get; set; } public int Drop { get; set; }
WaferLine에는 코팅에 사용할 Wafer와 코팅을 완료한 Wafer를 보관할 컬렉션이 필요하겠죠. 멤버 필드로 캡슐화할게요.
List<Wafer> bwafers = new List<Wafer>(); List<Wafer> awafers = new List<Wafer>();
WaferLine에서 하나의 Wafer를 코팅하면 bwafers에서 awafers에 옮겨야 하겠죠. 여기에서는 가장 최근에 코팅한 Wafer를 참조하는 속성을 제공할게요.
public Wafer LastWafer { get { if (awafers.Count == 0) { return null; } return awafers[awafers.Count - 1]; } }
중앙 관제에서는 WaferLine의 상태를 흉내내어 표현해야 합니다.
Wafer를 하나 코팅하였을 때 코팅 전과 코팅 후의 Wafer 컬렉션의 개수를 공장의 실제 WaferLine과 동기화해 주어야 합니다. 이를 위해 코팅 완료하였을 때 개수를 동기화하기 위한 메서드를 제공할게요.
public void EndCoating(int bwcnt, int awcnt) { while (bwafers.Count > bwcnt) { bwafers.RemoveAt(0); } while (awafers.Count < awcnt) { awafers.Add(null); } }
WaferLine에서 코팅하는 모습을 표현하기 위해 현재 코팅하는 Wafer를 참조하는 멤버 필드와 현재 코팅에 사용하는 코팅액의 남은 양을 멤버 필드로 캡슐화할게요.
Wafer nwafer; int nowp;//1병은 1000쉘을 코팅할 수 있다.
그리고 외부에서 현재 코팅하는 Wafer를 참조하는 속성을 제공합시다.
public Wafer Now { get { return nwafer; } }
코팅하기 전 Wafer 개수를 가져오기 할 수 있는 속성을 제공합시다.
public int BWCnt { get { return bwafers.Count; } }
코팅한 Wafer 개수를 가져오기 할 수 있는 속성도 제공합시다.
public int AWCnt { get { return awafers.Count; } }
코팅 액이 몇 병인지 기억하는 멤버도 캡슐화합시다.
public int PCnt { get; set; }
현재 코팅에 사용하는 코탱 액이 몇 개의 쉘을 코팅할 수 있는지 남은 양을 기억하는 속성도 제공합시다. 이 멤버는 현재 코팅에 사용하는 한 병에서 남은 양으로 몇 개의 쉘을 코팅할 수 있는 지를 나타냅니다.
public int NPcnt { get { return nowp; } }
코팅 액을 추가하는 메서드를 제공합시다. 여기에서는 최대 20병을 보관할 수 있게 하드코딩할게요.
보다 높은 품질로 구현하기 원하다면 보관할 수 있는 최대 병 수를 소프트코딩하세요.
public int InPr(int pcnt) { int avail = 20 - PCnt; if (pcnt > avail) { pcnt = avail; } PCnt += pcnt; return PCnt; }
회전 속도와 코팅 액 낙하 속도를 설정하는 메서드를 제공합시다.
public void SetSpin(int spin) { Spin = spin; } public void SetDrop(int drop) { Drop = drop; }
코팅할 때 품질은 랜덤하게 제공하는 것처럼 시뮬레이션하기 위해 랜덤 개체를 사용할게요.
Random rand = new Random();
하나의 쉘을 코팅하는 메서드를 제공합시다.
public bool Coating() {
코팅 액이 없으면 새로운 코팅액을 얻어옵니다. 하나의 병으로 코팅할 수 있는 쉘 수는 1000으로 하드코딩할게요.
if (nowp == 0) { if (PCnt == 0) { return false; } nowp = 1000; PCnt--; }
현재 코팅하는 Wafer가 null이라면 코팅하기 전 컬렉션에서 하나를 꺼내옵니다.
if (nwafer == null) { if (bwafers.Count == 0) { return false; } nwafer = bwafers[0]; bwafers.RemoveAt(0); }
현재 코팅하는 Wafer에 하나의 쉘을 코팅하는 메서드를 호출하고 남은 코팅 액을 1 감소합니다.
nwafer.Coating(rand.Next(70, 100)); nowp--;
현재 코팅하는 Wafer에 다음 코팅 쉘로 이동을 시킵니다. 만약 실패하면 코팅을 완료한 것이므로 코팅 완료한 컬렉션으로 옮기는 작업을 수행합니다.
if (nwafer.Increment() == false) { awafers.Add(nwafer); nwafer = null; } return true; }
ToString 메서드로 재정의합시다.
public override string ToString() { return string.Format("WaferLine No:{0}", No); }
WaferLine에 코팅 완료한 Wafer를 열거할 수 있게 정의합시다.
public class WaferLine : IEnumerable<Wafer> { ...생략... public IEnumerator<Wafer> GetEnumerator() { return awafers.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return awafers.GetEnumerator(); } }
2. WaferLine 클래스 소스 코드
다음은 현재까지 작성한 WaferLine 클래스 전체 소스 코드입니다.
using System; using System.Collections; using System.Collections.Generic; using WaferLineLib; namespace WaferLineLib { public class WaferLine : IEnumerable<Wafer> { public int No { get; } public int Spin { get; set; } public int Drop { get; set; } public WaferLine(int no) { No = no; Spin = 1000; Drop = 20; } List<Wafer> bwafers = new List<Wafer>(); List<Wafer> awafers = new List<Wafer>(); public Wafer LastWafer { get { if (awafers.Count == 0) { return null; } return awafers[awafers.Count - 1]; } } public void EndCoating(int bwcnt, int awcnt) { while (bwafers.Count > bwcnt) { bwafers.RemoveAt(0); } while (awafers.Count < awcnt) { awafers.Add(null); } } Wafer nwafer; int nowp;//1병은 1000쉘을 코팅할 수 있다. public Wafer Now { get { return nwafer; } } public int BWCnt { get { return bwafers.Count; } } public int InWafer(int wcnt) { int avail = 200 - BWCnt; if (wcnt > avail) { wcnt = avail; } for (int i = 0; i < wcnt; i++) { bwafers.Add(new Wafer()); } return bwafers.Count; } public int AWCnt { get { return awafers.Count; } } public int PCnt { get; set; } public int NPcnt { get { return nowp; } } public int InPr(int pcnt) { int avail = 20 - PCnt; if (pcnt > avail) { pcnt = avail; } PCnt += pcnt; return PCnt; } public void SetSpin(int spin) { Spin = spin; } public void SetDrop(int drop) { Drop = drop; } Random rand = new Random(); public bool Coating() { if (nowp == 0) { if (PCnt == 0) { return false; } nowp = 1000; PCnt--; } if (nwafer == null) { if (bwafers.Count == 0) { return false; } nwafer = bwafers[0]; bwafers.RemoveAt(0); } nwafer.Coating(rand.Next(70, 100)); nowp--; if (nwafer.Increment() == false) { awafers.Add(nwafer); nwafer = null; } return true; } public override string ToString() { return string.Format("WaferLine No:{0}", No); } public IEnumerator<Wafer> GetEnumerator() { return awafers.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return awafers.GetEnumerator(); } } }