# What Design Patterns Are Used in Wand Enhancer? A Technical Architecture Breakdown

> Explore Wand Enhancer design patterns like MVVM Command Singleton Bridge. Learn how this architecture separates UI from logic for maintainable cross-platform patch management.

- Repository: [k1tbyte/Wand-Enhancer](https://github.com/k1tbyte/Wand-Enhancer)
- Tags: architecture
- Published: 2026-07-13

---

**Wand Enhancer implements eight core software design patterns—including MVVM, Command, Singleton, and Bridge—to separate UI concerns from business logic and ensure maintainable cross-platform patch management for the Wand client.**

Wand Enhancer is an open-source patcher for the Wand desktop client that combines a WPF native interface with a modern Electron-based remote panel. Understanding what design patterns are used in Wand Enhancer reveals how the project maintains clean separation between platform-specific logic and UI components while handling complex ASAR file operations. The architecture deliberately applies classic software engineering patterns to create a modular, testable, and extensible codebase.

## Model-View-ViewModel (MVVM) and Observer Patterns

The **MVVM** pattern forms the architectural backbone of the WPF desktop application, implemented through base classes in [`WandEnhancer/ReactiveUICore/ObservableObject.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/WandEnhancer/ReactiveUICore/ObservableObject.cs). This pattern separates the XAML views from the underlying business logic, enabling data-binding and testable UI code.

The **Observer** pattern enables this separation via `INotifyPropertyChanged`. When properties change in the ViewModel, the Observer implementation notifies the view to update automatically:

```csharp
// Base implementation in ObservableObject.cs
public class ObservableObject : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

```

ViewModel classes in `WandEnhancer/View/MainWindow/` inherit from this base, exposing bindable properties that keep the UI synchronized with underlying data without tight coupling.

## Command Pattern for UI Actions

User interactions are encapsulated using the **Command** pattern through [`RelayCommand.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/RelayCommand.cs) and [`AsyncRelayCommand.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsyncRelayCommand.cs). This allows the XAML view to bind button clicks and menu actions to handlers without knowing the concrete implementation:

```csharp
public class MainWindowVm : ObservableObject {
    public RelayCommand OpenSettingsCommand { get; }

    public MainWindowVm() {
        OpenSettingsCommand = new RelayCommand(_ => OpenSettings());
    }

    private void OpenSettings() {
        // Logic that opens the Settings popup
    }
}

```

By treating user actions as objects, the Command pattern enables the view to remain declarative while the ViewModel maintains all execution logic and state.

## Singleton Pattern for Global Services

Configuration and localization services are managed as **Singletons** to ensure a single, globally accessible instance throughout the application lifecycle. The [`SettingsManager.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/SettingsManager.cs) and [`LocalizationManager.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/LocalizationManager.cs) in `Core/Services/` use lazy initialization:

```csharp
public sealed class SettingsManager {
    private static readonly Lazy<SettingsManager> _instance = 
        new(() => new SettingsManager(), true);

    public static SettingsManager Instance => _instance.Value;

    private SettingsManager() { 
        /* load persisted settings */ 
    }
}

```

The `true` parameter passed to `Lazy<T>` enables thread-safety, ensuring that even if multiple threads access `Instance` simultaneously, only one instance is created.

## Bridge Pattern for Cross-Process Communication

The Electron-based remote panel communicates with the native Wand client through the **Bridge** pattern. Defined in [`web-panel/bridge/src/websocket-codec.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/websocket-codec.ts), this abstraction decouples the Electron main process from renderer scripts:

```typescript
// Protocol definition in websocket-codec.ts
export interface BridgeMessage {
  op: string;
  data: unknown;
}

```

This well-defined IPC layer allows the remote web panel to exchange messages with the native client without either side knowing the other's implementation details, enabling independent evolution of the frontend and backend components.

## Factory and Builder Patterns for Archive Management

ASAR file operations—critical for patch injection—are handled using **Factory** and **Builder** patterns. The [`AsarCreator.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarCreator.cs) and [`AsarExtractor.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarExtractor.cs) classes in the `AsarSharp` namespace construct and read archives while hiding low-level file system complexity:

```csharp
// AsarCreator.cs – Factory method for creating archives
public static void Create(string sourceDir, string outputAsar) {
    // Implementation hides low-level file system handling
    // Returns a constructed ASAR archive without exposing internals
}

```

This encapsulation allows the rest of the application to work with high-level archive operations without managing the intricate details of the ASAR format.

## Strategy Pattern for Script Loading

The web-panel supports different runtime environments through the **Strategy** pattern. Files like [`web-panel/bridge/scripts/default/installed-apps-sync.js`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/scripts/default/installed-apps-sync.js) and the storage abstraction in [`web-panel/src/shared/storage.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/src/shared/storage.ts) allow different script implementations—such as development mocks versus production scripts—to be swapped at runtime while presenting a uniform API to the rest of the panel.

## Decorator Pattern for Data Conversion

WPF value converters extend functionality using a lightweight **Decorator** pattern. Classes like [`BaseBooleanConverter.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/BaseBooleanConverter.cs) and [`ToVisibilityConverter.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/ToVisibilityConverter.cs) in `WandEnhancer/Converters/` wrap existing conversion logic to add behavior without modifying the original converter classes, enabling flexible data transformation for XAML bindings.

## Summary

- **MVVM and Observer** patterns in [`ObservableObject.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/ObservableObject.cs) provide clean separation between WPF UI and business logic through data-binding and property notification.
- **Command** pattern via [`RelayCommand.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/RelayCommand.cs) encapsulates user actions as objects, keeping views declarative and ViewModels testable.
- **Singleton** pattern in [`SettingsManager.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/SettingsManager.cs) ensures thread-safe, global access to configuration services using lazy initialization.
- **Bridge** pattern in [`web-panel/bridge/src/websocket-codec.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/websocket-codec.ts) decouples the Electron main process from renderer scripts, enabling isolated IPC communication.
- **Factory/Builder** patterns in [`AsarCreator.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarCreator.cs) and [`AsarExtractor.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarExtractor.cs) abstract ASAR file construction and extraction, simplifying patch injection.
- **Strategy** pattern allows runtime swapping of script implementations in the web panel while maintaining consistent interfaces.
- **Decorator** pattern extends WPF converter functionality without altering original classes.

## Frequently Asked Questions

### Why does Wand Enhancer use MVVM instead of MVC for the WPF interface?

Wand Enhancer uses **MVVM** because it provides tighter integration with WPF's data-binding capabilities through `INotifyPropertyChanged`, allowing the ViewModel in `WandEnhancer/View/MainWindow/` to act as a specialized model for the view while remaining independent of the UI framework. This separation enables automated UI testing and allows designers to work with XAML without touching C# code, whereas MVC typically requires more manual synchronization between controllers and views.

### How does the Bridge pattern facilitate communication between the Electron panel and the native Wand client?

The **Bridge** pattern defines a protocol in [`web-panel/bridge/src/websocket-codec.ts`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/web-panel/bridge/src/websocket-codec.ts) that standardizes messages between the Electron main process and the renderer, creating an abstraction layer that prevents the web panel from depending on specific native implementation details. This decoupling allows the remote panel to communicate with the WPF backend through WebSocket messages without either component knowing the other's internal structure, making it possible to update the web interface independently of the native patcher.

### Are the Singleton implementations in Wand Enhancer thread-safe for concurrent access?

Yes, both [`SettingsManager.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/SettingsManager.cs) and [`LocalizationManager.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/LocalizationManager.cs) use `Lazy<T>` with the `true` parameter for thread-safety, ensuring that the singleton instance is created exactly once even if multiple threads simultaneously access the `Instance` property. This lazy initialization approach prevents race conditions during application startup while deferring object creation until first use.

### Which design pattern handles the extraction and creation of ASAR archive files during patching?

The **Factory** and **Builder** patterns handle ASAR operations through [`AsarCreator.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarCreator.cs) and [`AsarExtractor.cs`](https://github.com/k1tbyte/Wand-Enhancer/blob/main/AsarExtractor.cs), which encapsulate the complex file system logic required to construct and read ASAR archives. These classes present simple static methods like `Create()` to the rest of the application while internally managing the low-level byte manipulation and header construction specific to the ASAR format.