본문 바로가기
비전검사 기초 및 실무/비전 실무 프로젝트

「비전실무 프로젝트 9편」 유지보수가 쉬운 프로그램 구조 | 머신비전 소프트웨어 아키텍처 설계 방법

by eins-solutionlab 2026. 7. 14.

머신비전 프로젝트를 처음 개발할 때는 프로그램이 정상적으로 동작하는 것이 가장 중요합니다. 하지만 프로젝트가 완료된 이후에는 새로운 검사 항목이 추가되고, 카메라가 변경되거나 PLC와 MES가 교체되는 등 지속적인 수정이 이루어집니다.

이때 프로그램 구조가 잘 설계되어 있지 않으면 작은 기능 하나를 수정하기 위해 전체 코드를 변경해야 하는 상황이 발생합니다.

실제로 유지보수 비용은 초기 개발 비용보다 더 많이 발생하는 경우도 있습니다.

이번 글에서는 유지보수가 쉬운 머신비전 프로그램 구조, 폴더 구성, 클래스 설계, 모듈 분리 방법, 실패 사례와 실무 노하우를 자세히 알아보겠습니다.

유지보수가 중요한 이유

머신비전 프로그램은 한 번 개발하고 끝나는 프로그램이 아닙니다.

프로젝트가 완료된 이후에도 다음과 같은 요청이 계속 발생합니다.

  • 검사 항목 추가
  • 새로운 제품(Model) 추가
  • 카메라 교체
  • PLC 변경
  • AI 모델 교체
  • 검사 알고리즘 개선
  • UI 변경
  • MES 인터페이스 변경

프로그램 구조가 잘 설계되어 있다면 이러한 변경도 최소한의 수정으로 대응할 수 있습니다.

유지보수가 어려운 프로그램의 특징

다음과 같은 구조는 유지보수가 매우 어렵습니다.

MainForm.cs
↓
모든 코드 작성
↓
Camera
PLC
Vision
MES
Image Save
Log
Database
Statistics
모두 MainForm 안에 존재
 

이러한 구조는 흔히 God Object(거대한 객체) 라고 부르며, 코드가 수천~수만 줄까지 늘어나면 수정과 테스트가 매우 어려워집니다.

권장하는 프로그램 구조

실무에서는 기능별로 모듈을 분리하는 것이 가장 좋습니다.

VisionProject
├── Camera
├── Vision
├── PLC
├── MES
├── Database
├── Image
├── Log
├── Statistics
├── Configuration
├── Common
├── UI
└── Model
 

이처럼 기능별로 폴더를 분리하면 코드의 가독성과 재사용성이 크게 향상됩니다.

클래스 분리 예시

기능별로 클래스를 나누는 것이 좋습니다.

CameraManager
VisionManager
PLCManager
MESManager
ImageManager
LogManager
RecipeManager
StatisticsManager
ConfigManager
 

각 클래스는 자신의 역할만 담당해야 합니다.

예를 들어 CameraManager는 카메라 연결, 촬영, 해제만 처리하고 PLC 통신이나 이미지 저장은 담당하지 않습니다.

단일 책임 원칙(SRP)

좋은 프로그램 구조의 핵심은 하나의 클래스가 하나의 역할만 수행하는 것입니다.

예를 들어

❌ 나쁜 예

VisionManager
  ↓
Camera 연결
  ↓
PLC 통신
  ↓
Image 저장
  ↓
MES 전송
 

좋은 예

CameraManager
  ↓
ImageManager
  ↓
MESManager
  ↓
PLCManager
 

역할을 분리하면 기능 변경 시 다른 부분에 영향을 주지 않습니다.

설정 파일 관리

프로젝트가 커질수록 설정 값도 많아집니다.

추천 구조

Config
├── Camera.json
├── PLC.json
├── MES.json
├── Recipe.json
├── System.json
 

설정을 파일로 분리하면 프로그램을 다시 컴파일하지 않고도 변경할 수 있습니다.

Model(Recipe) 관리

제품별 검사 조건은 별도로 관리하는 것이 좋습니다.

Recipe
├── Connector_A
├── Connector_B
├── PCB_Model01
└── PCB_Model02
 

각 폴더에는 다음과 같은 파일을 저장합니다.

  • ROI 정보
  • 검사 파라미터
  • AI 모델
  • 템플릿 이미지
  • Calibration 데이터

이렇게 하면 새로운 제품이 추가되어도 기존 프로그램을 수정할 필요가 거의 없습니다.

이벤트 기반 구조 활용

모든 기능을 직접 호출하는 것보다 이벤트를 활용하면 결합도를 줄일 수 있습니다.

예를 들어

Camera Capture
  ↓
Image Captured Event
  ↓
Vision Inspection
  ↓
Inspection Complete Event
  ↓
Image Save
  ↓
Log Save
  ↓
MES Send
 

각 기능이 독립적으로 동작하여 유지보수가 쉬워집니다.

예외 처리(Exception) 통합

프로그램 전체에서 예외 처리를 일관되게 관리하는 것이 중요합니다.

예를 들어

try
  ↓
Error 발생
  ↓
Log 저장
  ↓
화면 표시
  ↓
관리자 알림
 

예외 처리를 각 클래스마다 따로 구현하기보다 공통 처리 클래스를 사용하는 것이 효율적입니다.

프로젝트 폴더 구성 예시

VisionInspection
│
├── Camera
├── Vision
├── PLC
├── MES
├── Recipe
├── Config
├── Image
├── Log
├── Database
├── Common
├── Utility
├── Models
├── Forms
└── Resources
 

이 구조는 대부분의 WinForms 기반 머신비전 프로젝트에서도 활용할 수 있습니다.

코드 재사용성을 높이는 방법

다음 기능은 공통 클래스로 만드는 것이 좋습니다.

  • 로그 저장
  • 파일 저장
  • 이미지 저장
  • JSON 읽기
  • CSV 저장
  • 시간 계산
  • 예외 처리
  • 메시지 출력

공통 기능을 모듈화하면 프로젝트마다 동일한 코드를 반복 작성하지 않아도 됩니다.

인터페이스(Interface) 활용

카메라나 PLC가 변경될 가능성이 있다면 인터페이스를 사용하는 것이 좋습니다.

예를 들어

ICamera
  ↓
BaslerCamera
HIKCamera
CognexCamera
 

나중에 카메라 제조사가 변경되어도 프로그램 전체를 수정할 필요 없이 해당 클래스만 교체하면 됩니다.

실패 사례

사례 1. MainForm.cs가 20,000줄까지 증가

모든 기능을 MainForm 하나에 작성한 프로젝트가 있었습니다.

작은 기능 하나를 수정해도 다른 기능에 영향을 주는 문제가 반복되었습니다.

해결 방법

  • 기능별 클래스 분리
  • UI와 로직 분리
  • 이벤트 기반 구조 적용

사례 2. PLC 변경 시 전체 프로그램 수정

PLC 통신 코드가 여러 파일에 흩어져 있어 새로운 PLC로 교체할 때 거의 모든 소스를 수정해야 했습니다.

해결 방법

PLCManager를 별도로 만들고 인터페이스를 적용하여 통신 모듈만 교체할 수 있도록 개선했습니다.

사례 3. 설정값이 코드에 하드코딩

카메라 IP, 저장 경로, 검사 기준값 등이 코드에 직접 작성되어 있었습니다.

설정을 변경할 때마다 프로그램을 다시 빌드해야 했습니다.

해결 방법

모든 설정을 JSON 또는 INI 파일로 분리하여 유지보수성을 높였습니다.

실무 노하우

프로젝트 경험상 가장 추천하는 구조입니다.

UI
 ↓
Controller
 ↓
Vision Manager
 ↓
Camera Manager
 ↓
PLC Manager
 ↓
MES Manager
 ↓
Database
 ↓
Log Manager
 ↓
Image Manager
 

이 구조는 각 기능이 독립적으로 동작하므로 새로운 기능을 추가하거나 수정하기가 쉽습니다.

유지보수 체크리스트

프로그램을 점검할 때 다음 사항을 확인해 보세요.

  • UI와 검사 로직이 분리되어 있는가?
  • 기능별 클래스로 모듈화되어 있는가?
  • 설정 파일이 외부로 분리되어 있는가?
  • 로그와 예외 처리가 통합되어 있는가?
  • 공통 기능을 재사용할 수 있는가?
  • 새로운 카메라나 PLC를 쉽게 교체할 수 있는가?
  • 제품(Recipe) 추가 시 코드 수정이 최소화되는가?
  • 폴더 구조가 명확하게 정리되어 있는가?

자주 묻는 질문(Q&A)

Q1. 작은 프로젝트도 이렇게 구조를 나누는 것이 좋나요?

네. 처음에는 다소 번거롭게 느껴질 수 있지만, 기능이 추가될수록 유지보수 시간이 크게 줄어듭니다.

Q2. UI와 검사 로직을 분리해야 하는 이유는 무엇인가요?

UI 변경이 검사 알고리즘에 영향을 주지 않고, 알고리즘 수정이 화면 구성에 영향을 주지 않기 때문입니다.

Q3. 설정 파일은 어떤 형식을 사용하는 것이 좋나요?

최근에는 JSON 형식을 가장 많이 사용하며, 간단한 프로젝트에서는 INI 파일도 많이 활용됩니다.

Q4. 인터페이스를 꼭 사용해야 하나요?

필수는 아니지만, 카메라·PLC·MES처럼 변경 가능성이 높은 장비를 사용하는 경우에는 유지보수성과 확장성이 크게 향상됩니다.

Q5. 가장 중요한 설계 원칙은 무엇인가요?

하나의 클래스는 하나의 역할만 담당하도록 설계하는 것(Single Responsibility Principle) 입니다. 이 원칙만 잘 지켜도 코드 품질과 유지보수성이 크게 향상됩니다.

마무리

유지보수가 쉬운 프로그램은 처음부터 모듈화, 역할 분리, 설정 파일 관리, 공통 기능 재사용을 고려하여 설계해야 합니다.

실무에서는 UI와 로직 분리, Manager 클래스 구조, 이벤트 기반 처리, 인터페이스 활용, 외부 설정 파일 관리를 적용하면 프로젝트 규모가 커져도 안정적으로 운영할 수 있습니다.

이러한 구조는 개발 속도뿐 아니라 유지보수 비용 절감과 기능 확장에도 큰 도움이 됩니다.

다음 편에서는 **「50편 비전검사 프로젝트 구축 체크리스트」**를 통해 프로젝트 시작부터 설치, 시운전, 운영까지 반드시 확인해야 할 핵심 체크 항목을 정리해보겠습니다.