본문 바로가기

Delphi201

클래스(Class) 기반 객체 설계 기초 클래스(Class) 기반 객체 설계 기초 클래스(Class)는 객체지향 프로그래밍(OOP)의 기본 단위로, 데이터(필드)와 동작(메서드)을 하나의 구조로 묶어 유지보수성을 높입니다. 현실 객체를 클래스로 표현하면 비즈니스 로직 분리와 확장이 쉬워집니다. Delphi는 자동 메모리 해제 기능이 없으므로, try..finally로 객체를 직접 관리해야 합니다. program ClassDemo; {$APPTYPE CONSOLE} uses System.SysUtils; type TEmployee = class private FEmpNo: Integer; FName: string; FSalary: Currency; public constructor Create(AEmp.. 2025. 10. 17.
포인터 안전하게 다루기 (Pointer & Memory Handling) 포인터 안전하게 다루기 (Pointer & Memory Handling)포인터(Pointer)는 메모리 주소를 직접 다루는 강력한 기능이지만, 잘못 쓰면 프로그램이 즉시 크래시합니다. @, ^ 연산자를 통해 메모리 접근이 가능하며, GetMem/FreeMem으로 수동 관리할 수 있습니다. 포인터보다 레코드, 배열, 객체를 우선 사용하되, 파일 입출력, 네트워크 송수신, DLL 연동 시 포인터가 꼭 필요합니다. program PointerDemo; {$APPTYPE CONSOLE} uses System.SysUtils; type PInt = ^Integer; var Ptr: PInt; begin New(Ptr); // 메모리 할당 try Ptr^ := 12.. 2025. 10. 16.
레코드(Record)로 데이터 구조 최적화하기 레코드(Record)로 데이터 구조 최적화하기 record는 클래스보다 가벼운 구조체형 데이터 컨테이너로, 스택(Stack)에 저장되어 빠르고 메모리 효율적입니다. 단순 데이터 그룹을 표현할 때 적합. packed record를 사용하면 메모리 정렬 패딩을 제거해 파일 입출력 시 크기를 최소화할 수 있습니다. program RecordDemo; {$APPTYPE CONSOLE} uses System.SysUtils; type TEmployee = record EmpNo: Integer; Name: string[30]; Salary: Currency; JoinDate: TDateTime; function GetInfo: string; end; TPack.. 2025. 10. 15.
동적 배열로 유연한 데이터 처리하기 동적 배열로 유연한 데이터 처리하기 고정 배열은 크기가 컴파일 시점에 결정되지만, **동적 배열(Dynamic Array)**은 런타임에서 크기를 조정할 수 있음. ERP/SI 시스템에서 사용자 입력, 조회 결과 등 크기를 알 수 없는 데이터를 저장할 때 필수적. SetLength로 크기를 변경 가능, 반복문(for-in)으로 가독성 있게 순회 가능. // ✅ Delphi 11+ : 동적 배열 program DynamicArrayDemo; {$APPTYPE CONSOLE} uses System.SysUtils; var Arr: TArray; I: Integer; begin SetLength(Arr, 5); // 배열 크기 지정 for I := 0 to High(Arr) do .. 2025. 10. 2.
메모리 스트림(TMemoryStream) 활용하기 메모리 스트림(TMemoryStream) 활용하기 TMemoryStream은 메모리에 데이터를 임시 저장하는 스트림 클래스입니다. 왜 유용한가: 파일 I/O보다 빠르고, 데이터 직렬화/역직렬화, 네트워크 전송 등 중간 버퍼 용도로 많이 사용됩니다. DB BLOB 데이터 처리 사용 이미지/파일 압축 전 메모리 버퍼 사용 암호화 전후 변환 단계 사용 program MemoryStreamDemo; {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes; procedure RunDemo; var ms: TMemoryStream; s: string; buffer: TBytes; begin ms := TMemoryStream.Create; try .. 2025. 10. 1.
안전한 if..else와 case 구문: Nullable 대응 패턴 안전한 if..else와 case 구문: Nullable 대응 패턴 if..else와 case는 분기 제어의 핵심 문법. Delphi 11+에서는 Nullable로 DB NULL 값도 안전하게 처리. 레거시(Delphi 7/XE)는 VarIsNull/Assigned 활용. ERP/SI 환경에서 DB 값이 비어 있을 때 예외 방지 및 안정적 분기 처리. // ✅ Delphi 11+ : Nullable와 case 결합 program NullableDemo; {$APPTYPE CONSOLE} uses System.SysUtils, System.Generics.Defaults; var Discount: Nullable; begin Discount := Null; // DB에서 값 없음 if no.. 2025. 9. 30.
TCriticalSection으로 멀티스레드 동기화하기 (Advanced) TCriticalSection으로 멀티스레드 동기화하기 (Advanced) 델파이(Delphi)에서 멀티스레드를 활용하면 성능을 높일 수 있지만, 동시에 여러 스레드가 같은 리소스를 접근하면 데이터 충돌이나 불안정한 동작이 발생할 수 있습니다. 이를 방지하기 위해 TCriticalSection을 사용하면 특정 코드 블록을 한 번에 하나의 스레드만 실행하도록 보호할 수 있습니다. uses System.SysUtils, System.Classes; var Counter: Integer; procedure Worker; var I: Integer; begin for I := 1 to 1000000 do Inc(Counter); // 여러 스레드가 동시에 접근 → 잘못된 값 발생 가.. 2025. 9. 25.
Generics.Collections로 타입 안전한 리스트 사용하기 (Beginner) Generics.Collections로 타입 안전한 리스트 사용하기 (Beginner) 델파이(Delphi)에서는 TList 같은 일반 리스트가 있지만, 모든 데이터를 Pointer로 다루어 타입 변환 과정에서 실수할 위험이 있습니다. Generics.Collections의 TList를 사용하면 타입 안전성과 가독성을 높일 수 있습니다. uses System.Generics.Collections, System.SysUtils; procedure Demo; var Numbers: TList; I: Integer; begin Numbers := TList.Create; try Numbers.Add(10); Numbers.Add(20); Numbers.Add(30);.. 2025. 9. 24.
인터페이스(Interface) 활용하기 (Advanced) 인터페이스(Interface) 활용하기 (Advanced)델파이(Delphi)에서 interface는 다형성과 의존성 분리를 구현하는 핵심 도구입니다. 대규모 프로젝트나 플러그인 구조를 설계할 때 클래스 간 결합도를 낮추고 유지보수성을 높이는 데 큰 도움이 됩니다. uses System.SysUtils; type // 인터페이스 정의 IGreeter = interface ['{7E95F0B8-5F43-4C5A-A8D9-13B8E8F8C2D7}'] procedure SayHello(const Name: string); end; // 구현 클래스 TConsoleGreeter = class(TInterfacedObject, IGreeter) public pr.. 2025. 9. 19.
for..in 반복문으로 컬렉션 다루기 (Beginner) for..in 반복문으로 컬렉션 다루기 (Beginner) 델파이(Delphi)에서 배열이나 제네릭 컬렉션을 다룰 때, 전통적인 for i := 0 to ... 문보다 for..in 반복문을 쓰면 코드가 간결하고 읽기 쉬워집니다. 특히 TList나 TDictionary 같은 제네릭 타입에서 활용도가 높습니다. uses System.SysUtils; procedure DemoArray; var Names: array of string; Name: string; begin Names := ['Alice', 'Bob', 'Charlie']; for Name in Names do Writeln('Hello, ' + Name); end; begin DemoArray; end. .. 2025. 9. 18.
with 구문 사용의 장단점 (Intermediate) with 구문 사용의 장단점 (Intermediate) 델파이(Delphi)에서는 with 구문을 이용해 특정 객체의 속성이나 메서드를 간결하게 호출할 수 있습니다. 그러나 잘못 사용하면 코드 가독성과 유지보수성에 악영향을 줄 수 있습니다. 언제 with를 쓰고, 언제 피해야 하는지 이해하는 것이 중요합니다. uses Vcl.Forms, Vcl.StdCtrls; procedure TForm1.FormCreate(Sender: TObject); var Btn: TButton; begin Btn := TButton.Create(Self); with Btn do begin Parent := Self; Caption := '클릭하세요'; Left := 50; .. 2025. 9. 16.
Record Helpers로 코드 가독성 높이기 (Intermediate) Record Helpers로 코드 가독성 높이기 (Intermediate) 델파이(Delphi)에서 record는 가벼운 데이터 구조체로 자주 사용됩니다. 하지만 기능이 제한적일 수 있습니다. record helper를 사용하면 기존 record에 메서드나 속성을 확장해 넣을 수 있어, 코드의 가독성과 재사용성을 크게 향상시킬 수 있습니다. uses System.SysUtils; type TPoint = record X, Y: Integer; end; // Record Helper 선언 TPointHelper = record helper for TPoint function ToString: string; function DistanceTo(const P: TP.. 2025. 9. 10.
TMonitor를 이용한 객체 동기화 (Advanced) TMonitor를 이용한 객체 동기화 (Advanced)멀티스레드 환경에서 여러 스레드가 동일한 객체에 접근할 경우, 동기화가 필요합니다. TCriticalSection은 프로세스 내 자원 보호에 유용하지만, 델파이(Delphi)에서는 TMonitor라는 더 현대적이고 객체 지향적인 동기화 방법을 제공합니다. TMonitor는 객체 자체에 대한 잠금(lock)을 제공하며, Wait, Pulse, PulseAll을 통해 스레드 간 조건 동기화도 가능하게 합니다. uses System.SysUtils, System.Classes; type TSharedBuffer = class private FData: string; public procedure WriteData(.. 2025. 9. 5.
TCriticalSection으로 멀티스레드에서 자원 보호하기 (Intermediate) TCriticalSection으로 멀티스레드에서 자원 보호하기 (Intermediate)델파이(Delphi)에서 멀티스레드 프로그램을 작성할 때, 여러 스레드가 동시에 같은 변수나 객체를 수정하면 Race Condition(경쟁 상태) 이 발생할 수 있습니다. 이런 문제를 막으려면 스레드 간에 공유되는 자원 접근을 동기화해야 합니다. TCriticalSection은 간단하게 임계 구역(critical section)을 설정하여 한 번에 한 스레드만 진입하도록 보장합니다. uses System.Classes, System.SyncObjs, System.SysUtils; var Counter: Integer = 0; CS: TCriticalSection; procedure Incremen.. 2025. 9. 4.
Exit로 함수 흐름 단순화하기 (Beginner) Exit로 함수 흐름 단순화하기 (Beginner)델파이(Delphi)에서는 Exit 구문을 사용해 함수나 프로시저의 실행을 즉시 종료할 수 있습니다. 조건에 따라 빠르게 함수를 탈출하면 가독성이 좋아지고, 중첩된 if문을 줄일 수 있습니다. 단, 객체 해제 같은 정리 작업은 try..finally 블록 안에서 처리해야 합니다. function IsAdult(Age: Integer): Boolean; begin if Age Exit(False); // 잘못된 입력이면 바로 종료 if Age >= 18 then Exit(True); Result := False; // 그 외에는 False end; procedure TestExit; begin if IsAdult(20) .. 2025. 8. 27.
Delphi에서 제네릭 리스트(TList<T>) 효율적으로 사용하기 (Intermediate) Delphi에서 제네릭 리스트(TList) 효율적으로 사용하기 (Intermediate) 델파이(Delphi)에서 TList는 제네릭을 지원하는 강력한 리스트 컬렉션으로, 타입 안정성과 성능을 모두 제공합니다. 기존의 TList는 Pointer 기반이라 형변환이 필요했지만, TList는 컴파일 타임에 타입이 고정되어 안전합니다. 또한 for..in 구문과 함께 사용하면 더 직관적인 코드 작성이 가능합니다. uses System.Generics.Collections, System.SysUtils; procedure TestGenericList; var Numbers: TList; I: Integer; begin Numbers := TList.Create; try // 값 추가.. 2025. 8. 13.
익명 메서드로 코드 가독성 향상하기 익명 메서드로 코드 가독성 향상하기 익명 메서드는 로컬 변수처럼 선언되어 특정 코드 블록 내에서만 사용 가능한 메서드입니다. 주로 콜백 함수, 정렬, 스레딩, 이벤트 핸들링 등에서 유용하며 코드 가독성을 높이고 메서드 분리를 최소화할 수 있습니다. procedure TForm1.Button1Click(Sender: TObject); var Multiply: reference to function(A, B: Integer): Integer; Result: Integer; begin Multiply := function(A, B: Integer): Integer begin Result := A * B; end; Result := Multiply(6, 7); S.. 2025. 8. 6.
TStringHelper를 이용한 문자열 분할과 트리밍 TStringHelper를 이용한 문자열 분할과 트리밍 델파이의 TStringHelper는 string 타입에 유용한 메서드를 확장해주는 기능입니다. 특히 Split, Trim, ToUpper 등은 문자열 처리에서 자주 사용되며 가독성도 크게 향상됩니다. uses System.SysUtils, System.Classes; procedure ParseUserInput(const Input: string); var Parts: TArray; Name, Email: string; begin Parts := Input.Split([',']); // 콤마 기준으로 분할 if Length(Parts) >= 2 then begin Name := Parts[0].Trim; Emai.. 2025. 8. 4.
레코드를 객체처럼 다루기: 메서드 포함 레코드 레코드를 객체처럼 다루기: 메서드 포함 레코드 델파이의 record는 단순한 데이터 저장용으로 쓰이지만, 메서드나 생성자도 정의할 수 있어 객체처럼 활용할 수 있습니다. 이 기법은 간단한 구조 데이터에 기능을 부여하고자 할 때 유용합니다. type TEmployee = record Name: string; Salary: Currency; procedure RaiseSalary(Amount: Currency); function GetInfo: string; end; procedure TEmployee.RaiseSalary(Amount: Currency); begin Salary := Salary + Amount; end; function TEmployee.GetI.. 2025. 8. 1.
TTask를 이용한 백그라운드 작업 처리 TTask를 이용한 백그라운드 작업 처리 Systehttp://m.Threading.TTask를 활용하면 UI를 멈추지 않고 백그라운드에서 작업을 처리할 수 있습니다. 예를 들어, 긴 로직이나 서버 통신을 처리할 때 UI 응답성을 유지하면서 동시에 병렬 처리를 구현할 수 있습니다. uses System.Threading, System.SysUtils, Vcl.Dialogs; procedure DoBackgroundWork; begin TTask.Run( procedure begin Sleep(3000); // 3초 동안 작업 수행 TThread.Synchronize(nil, procedure begin Show.. 2025. 7. 31.