WPF App.xaml.cs static 사용 질문

안녕하세요.

wpf로 의료기기 GUI 작업을 하고 있습니다.

Firmware와 rs232통신을 많이 사용하기 때문에

App.xaml.cs에다가 아래 처럼 사용하고 있습니다.

    public staitc Serial_rs232 serial_rs232;

    public App()
    {
        serial_rs232 = new Serial_rs232
    }

이렇게 하고 아래 처럼 사용하고 있습니다.

App.serial_rs232.SendToSystem();

이렇게 사용 하는 이유는
어디서든 접근가능하면서 Firmware로 통신 데이터를 보낼 수 있도록
하기 위함인데요

wpf에서 보통 단일 인스턴스로 관리하면서 어디서든 접근하여 제어가 가능하도록 하려고 할 때 어떤 방식으로 코드를 작성할까요?

제가 쓰는 방식은 너무 무식한 방법인거 같아서요^^;;

2개의 좋아요

무식한 방법은 아닌 것 같습니다.
말씀하신 방법으로 하시는게 보기에는 깔끔하지요. 어디서든 Static으로 접근가능하니까요.
여기서 조금 있어보이게? 하고 싶으시면 IoC 컨테이너를 도입하셔서 싱글턴 인스턴스를 만드셔서 작업하시는 것인데, 필요성을 못느끼신다면 그냥 지금처럼 하셔도 될 것 같습니다.

Static 클래스에 Static 맴버를 필요이상으로 때려 넣어서 스파게티 코드가 되어 소프트웨어적인 구조를 해치기 때문에 static을 지양 하는 것이지, 적절하게 써주면 이것만큼 편리한 기능도 없다고 생각합니다.

다른 분들이 더 좋은 의견 주실 수는 있으나, 지금 방식이 나쁘다고 생각하지는 않습니다.

2개의 좋아요

@Vincent 저도 동감합니다. :smile:

@정이현 아마 성격은 다를 것 같지만
저도 최근에 구현한 부분이 있는데요.

저는 이런식으로도 해보고 있습니다. App.cs

main.DataContext = new MainViewModel(Theme, Culture);

public class App : FlowApp
{
    protected override ThemeType OnSetDefaultTheme(ThemeType type) 
        => ThemeType.Dark;

    protected override void OnApplyThemeManager()
    {
        AddTheme(ThemeType.Dark, "Generic.Dark.xaml");
        AddTheme(ThemeType.White, "Generic.White.xaml");
        AddTheme(ThemeType.James, "Generic.James.xaml");
        AddTheme(ThemeType.Elena, "Generic.Elena.xaml");
    }

    protected override void OnApplyCultureManager()
    {
        AddLanguage(LanguageType.UnitedStates, "EN.xaml");
        AddLanguage(LanguageType.Korea, "KO.xaml");
        AddLanguage(LanguageType.China, "CN.xaml");
        AddLanguage(LanguageType.Japan, "JP.xaml");
    }

    protected override void OnStartup(StartupEventArgs e)
    {
        bool dialogResult = true;

        ConfigModel config = FlowConfig.LoadConfig();

        Theme.Switch(config.Theme);
        Culture.Switch(config.Language);

        while (dialogResult)
        {
            ShutdownMode = ShutdownMode.OnExplicitShutdown;
            var main = new MainView();
            main.DataContext = new MainViewModel(Theme, Culture);
            main.ShowDialog();
            dialogResult = (bool)main.DialogResult;
        }
        Environment.Exit(0);
    }
}
1개의 좋아요

저는 다른 관점에서 의견을 드려보겠습니다.

먼저, 저는 정적 클래스 사용을 극도로 제한 합니다. 이유는 소스코드가 어느정도 규모가 되면 관리가 힘들어지거든요. 그리고 정적 클래스로 사용하다 보면, 추상 클래스 또는 인터페이스를 활용하는 방법에 소홀에지게 됩니다. 공유 주신 코드로 예를 들어 보겠습니다.

   App.serial_rs232.SendToSystem();

Firmware와 RS232 통신을 하기 위해 위에 처럼 사용을 하실 텐데요, 사실, 펌웨워와 RS232 통신은 직접적인 관련이 없습니다. 즉, SendToSystem()이라는 메소드를 사용하기 위해서 RS232를 사용하는 코드와 코드 응집력이 생기는 것은 객체지향 관점에서 좋지 않습니다. (그만큼 뭘 수정할 때 고쳐야 할게 많아진다고 이해하시면 됩니다.)

대신, 인터페이스를 사용해서 기능을 추상화 하고 그 기능을 사용하는 로직에 Serial_rs232 대신 IFirmwareCommand 등으로 사용을 합니다. 이제, 더이상 그 로직에는 Serial_rs232와 관련이 없게 됩니다.

위의 이유와는 상관은 없지만, 정적 클래스를 사용하는것을 지양하고 이런 인터페이스 인스턴스를 인자로 받아 처리하게 되면, 자연스럽게 로직의 클래스가 어떤 인스턴스와 관련이 생기는지를 코드로 확인할 수 있게 되고, 그러다보면, 코드 응집력을 낮추기 위해 인터페이스 또는 추상 클래스를 사용하려는 흐름이 생기게 됩니다. 그러면 코딩 시간이 누적되더라도 전반적인 코드가 그러한 응집력 없이 모듈화 될 수 있게 됩니다.

5개의 좋아요

@dimohy 저도 여기에 한 표 하겠습니다.
ViewModel 프로젝트를 분리하여 MVVM 패턴을 엄격하게 구현할 경우, App 클래스의 접근이 어려울 수도 있습니다.
또한 기능이나 성격이 App에서 가져야할 것은 아니기 기본적으로 분리를 하는 것이 좋아보입니다.
시리얼 통신을 위한 별도의 서비스(프로젝트 수준의 분리 추천)를 만들고 이를 인터페이스로만 호출할 수 있도록 한 다음 실제로 사용하는 위치에서는 DI 로 획득해 호출하는 것이 가장 좋다고 생각합니다.

4개의 좋아요

프로그래밍 언어에 대한 질문이 아닌 Windows Forms 질문이어서 카테고리를 변경해드립니다.

2개의 좋아요