> 백엔드 개발 > Golang > 기술 보고서: Go에서 동시 주차 시뮬레이터 개발

기술 보고서: Go에서 동시 주차 시뮬레이터 개발

Susan Sarandon
풀어 주다: 2024-12-24 19:40:11
원래의
202명이 탐색했습니다.

Reporte Técnico: Desarrollo de un Simulador de Estacionamiento Concurrente en Go

소개

이 프로젝트는 사용자 인터페이스로 Fyne 그래픽 라이브러리를 사용하여 Go에서 개발된 동시 주차 시뮬레이터로 구성됩니다. 그 목적은 주차장의 동작을 실시간으로 모델링하여 차량의 출입을 동시에 관리하고 주차 공간의 업데이트된 상태를 시각적으로 보여주는 것입니다.
이 프로젝트는 동시성 개념, Observer 디자인 패턴 및 동적 렌더링을 그래픽 인터페이스에 결합합니다. 이 보고서는 다른 개발자에게 기술 참조를 제공하는 것을 목표로 이러한 도구의 사용, 직면한 과제(특히 Observer 및 Fyne 패턴에서), 해결 방법을 자세히 설명합니다.

1. 파인 초기화

Fyne은 Go를 사용하여 그래픽 인터페이스를 개발하기 위한 최신 라이브러리입니다. 기본 초기화는 다음 단계를 따릅니다.

  1. app.New()를 사용하여 새 애플리케이션을 만듭니다.
  2. app.NewWindow()를 사용하여 기본 창을 구성합니다.
  3. Fyne 컨테이너와 위젯을 활용하여 콘텐츠를 디자인하세요.
  4. ShowAndRun()을 호출하여 애플리케이션을 실행합니다.

시뮬레이터에서는 주차장 뷰를 통합하고 동시 논리 모델에 연결하는 메인 창이 생성되었습니다.

func main() {
    myApp := app.New()
    mainWindow := myApp.NewWindow("Simulador de Parking")

    estacionamiento := models.NewEstacionamiento(20)
    parkingView := views.NewParkingView()

    mainScene := scenes.NewMainScene(estacionamiento, parkingView)
    mainWindow.SetContent(parkingView.Container)

    mainWindow.ShowAndRun()
}

로그인 후 복사
로그인 후 복사
로그인 후 복사

이 기본 흐름은 비즈니스 로직과 그래픽 인터페이스 간의 분리를 용이하게 합니다.

2. 관찰자 패턴 사용

관찰자 패턴을 사용하는 이유

모델 레이어와 뷰 레이어의 동기화를 유지하기 위해 관찰자 패턴이 사용되었습니다. 차량이 주차장에 들어오거나 나갈 때 모델은 해당 그래픽 요소를 업데이트하는 뷰를 알려줍니다. 이 패턴은 여러 구성요소가 동일한 이벤트에 반응해야 하는 시스템에 이상적입니다.

Go에서 Observer 패턴을 사용할 때 발생하는 문제

Go에서 Observer 패턴을 구현하는 것은 어려울 수 있습니다. 특히 Java나 C#과 같은 객체 지향 언어로 구현하는 데 익숙한 사람들에게는 더욱 그렇습니다. Go에서 이 패턴을 사용하는 일반적인 문제는 관찰자에게 알릴 때 동시성 및 교착 상태를 처리하는 것입니다.

처음에는 모델(주차장)에 등록된 관찰자를 반복하여 이벤트를 보고했는데 경합 조건이 발생하고 충돌이 발생했습니다. 이는 새로운 관찰자를 등록하는 메소드가 제대로 보호되지 않아 관찰자 목록에 동시 접근이 발생했기 때문에 발생했습니다.

해결 방법
이 문제를 해결하기 위해 관찰자 목록에 대한 동시 접근을 보호하기 위해 뮤텍스(sync.Mutex)를 사용했습니다. 또한 관찰자를 등록하고 이벤트를 보고하는 안전한 방법이 구현되었습니다.

func main() {
    myApp := app.New()
    mainWindow := myApp.NewWindow("Simulador de Parking")

    estacionamiento := models.NewEstacionamiento(20)
    parkingView := views.NewParkingView()

    mainScene := scenes.NewMainScene(estacionamiento, parkingView)
    mainWindow.SetContent(parkingView.Container)

    mainWindow.ShowAndRun()
}

로그인 후 복사
로그인 후 복사
로그인 후 복사

프로젝트 전체 구현
주차장 모델은 관찰 가능한 주체 역할을 하고 MainScene 및 그래프 뷰와 같은 기타 구성 요소는 관찰자 역할을 합니다.
1. 관찰자 인터페이스 정의:

func (e *Estacionamiento) RegistrarObservador(o Observer) {
    e.mu.Lock()
    defer e.mu.Unlock()
    e.observadores = append(e.observadores, o)
}

func (e *Estacionamiento) NotificarVehiculoEntra(id, cajon, espaciosDisponibles, capacidad int) {
    e.mu.Lock()
    defer e.mu.Unlock()
    for _, o := range e.observadores {
        o.OnVehiculoEntra(id, cajon, espaciosDisponibles, capacidad)
    }
}

func (e *Estacionamiento) NotificarVehiculoSale(id, cajon, espaciosDisponibles, capacidad int) {
    e.mu.Lock()
    defer e.mu.Unlock()
    for _, o := range e.observadores {
        o.OnVehiculoSale(id, cajon, espaciosDisponibles, capacidad)
    }
}
로그인 후 복사
  1. 모델의 이벤트 알림:
package models

type Observer interface {
    OnVehiculoEntra(id, cajon, espaciosDisponibles, capacidad int)
    OnVehiculoSale(id, cajon, espaciosDisponibles, capacidad int)
}

로그인 후 복사
  1. 관찰자 반응:
func (e *Estacionamiento) VehiculoEntra(id int) {
    // Lógica para manejar la entrada del vehículo
    espaciosDisponibles := e.capacidad - e.ocupados
    e.NotificarVehiculoEntra(id, cajon, espaciosDisponibles, e.capacidad)
}

func (e *Estacionamiento) VehiculoSale(id int) {
    // Lógica para manejar la salida del vehículo
    espaciosDisponibles := e.capacidad - e.ocupados
    e.NotificarVehiculoSale(id, cajon, espaciosDisponibles, e.capacidad)
}
로그인 후 복사

이 솔루션은 업데이트가 일관되게 유지되고 경합 상태가 시스템 성능에 영향을 미치지 않도록 보장합니다.

3. 기술적 문제: 렌더링 및 위치 계산

컨텍스트

가장 기술적 과제는 그래픽 인터페이스에서 서랍의 위치를 ​​계산하고 색상을 실시간으로 업데이트하는 것이었습니다. 서랍은 다음을 충족해야 합니다.

  1. 두 줄로 간격을 두고 배열하세요.
  2. 색상을 동적으로 변경합니다(바쁨은 빨간색, 비어 있음은 검은색).

확인된 문제

  1. 동적 위치 계산: 주차 공간은 두 줄로 균일한 간격으로 배치되어야 했습니다. 그러나 이러한 위치를 계산하고 업데이트하는 것은 레이아웃이 없는 컨테이너(container.NewWithoutLayout()) 내의 정확한 좌표에 의존하기 때문에 복잡했습니다.
  2. 시각적 동기화: 여러 개의 동시 스레드를 처리할 때 서랍 색상을 실시간으로 업데이트하려고 할 때 시각적 불일치가 발생했습니다. 변경사항이 반영되지 않거나 그래픽 오류가 발생하는 경우도 있었습니다.

직위계산
초기 위치와 간격을 정의하기 위해 절대 좌표가 사용되었습니다.

func (s *MainScene) OnVehiculoEntra(id, cajon, espaciosDisponibles, capacidad int) {
    s.View.UpdateState(espaciosDisponibles, capacidad, id, cajon, "entra")
}

func (s *MainScene) OnVehiculoSale(id, cajon, espaciosDisponibles, capacidad int) {
    s.View.UpdateState(espaciosDisponibles, capacidad, id, cajon, "sale")
}
로그인 후 복사

동적 렌더링
상태에 따라 서랍을 칠하는 기능이 구현되었습니다.

xStart, yTop, yBottom := float32(185), float32(120), float32(200)
spotSpacing := float32(55)

// Fila superior
for i := 0; i < 10; i++ {
    parkingSpots = append(parkingSpots, fyne.Position{X: xStart + float32(i)*spotSpacing, Y: yTop})
}

// Fila inferior
for i := 0; i < 10; i++ {
    parkingSpots = append(parkingSpots, fyne.Position{X: xStart + float32(i)*spotSpacing, Y: yBottom})
}
로그인 후 복사

시각적 동기화
시각적 변화가 시스템 상태와 일관되도록 하기 위해 기본 라벨 텍스트와 서랍 상태가 중앙 기능 내에서 업데이트되었습니다.

func main() {
    myApp := app.New()
    mainWindow := myApp.NewWindow("Simulador de Parking")

    estacionamiento := models.NewEstacionamiento(20)
    parkingView := views.NewParkingView()

    mainScene := scenes.NewMainScene(estacionamiento, parkingView)
    mainWindow.SetContent(parkingView.Container)

    mainWindow.ShowAndRun()
}

로그인 후 복사
로그인 후 복사
로그인 후 복사

이를 통해 항상 정확한 최신 그래픽 표현이 보장됩니다.

결론

이 프로젝트는 동시 주차 시뮬레이션이라는 목표를 달성했을 뿐만 아니라 Observer 패턴을 사용하고 Fyne을 사용하여 그래픽 인터페이스를 만드는 등 실질적인 개발 문제에 직면해 있습니다. 직면한 문제와 구현된 솔루션은 Go를 시작하거나 유사한 문제에 직면한 다른 개발자에게 지침 역할을 하기 위한 것입니다.
특히 Go의 Observer 패턴 구현은 동시성을 안전하고 효율적으로 처리하는 방법을 보여줍니다. 이 보고서는 이러한 문제와 솔루션을 문서화함으로써 이러한 도구를 학습하고 적용하는 데 관심이 있는 프로그래머 커뮤니티에 기여하고 학습 및 개발 프로세스를 촉진하는 것을 목표로 합니다.
구현 및 솔루션에 대해 질문이 있는 경우 내 Github 저장소인 simulador-parking.git

를 참조하세요.

위 내용은 기술 보고서: Go에서 동시 주차 시뮬레이터 개발의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿