Main Content

MATLAB クラスを使用したアプリ データの整理

アプリのサイズと複雑度が増すと、計算、データ処理、およびユーザー操作管理を行うコードを 1 つのファイル内で整理して管理するのが難しい場合があります。この例では、App Designer のみで作成されたアプリを使用して、アプリ コードを次の 2 つの部分に再編成する方法を説明します。

  • アプリ データと、そのデータを処理するアルゴリズムを保存するコード。MATLAB® クラスとして実装されます。

  • アプリを表示し、ユーザー操作を管理するコード。App Designer アプリとして実装されます。

データとアルゴリズムをアプリから分離することには、以下の複数のメリットがあります。

  • スケーラビリティ — コードが複数の自己完結部分に整理されていると、アプリ機能を簡単に拡張できます。

  • 再利用性 — 最小限の作業でデータとアルゴリズムを複数のアプリに再利用できます。

  • テスト容易性 — アプリとは別に、MATLAB でアルゴリズムを実行およびテストできます。

この例では PulseGenerator アプリを使用します。ユーザーはこのアプリを使用して、パルス生成のオプションと、結果の波形を可視化するオプションを指定できます。この例の目標は、以下の手順を実行して元のアプリのコードを再編成することです。

  1. パルスのタイプ、周波数、長さなどのパルス データと、そのパルス データを取得して結果の波形を生成するためのアルゴリズムとを保存する、Pulse クラスを作成します。

  2. Pulse クラスを使用して計算を実行し、アプリの表示を更新するように、App Designer でコードを変更します。

最終的なアプリでは、ユーザーがアプリ コントロールを操作すると、App Designer のコードにより Pulse クラスに保存されているデータが更新され、波形データを生成するクラス メソッドが呼び出されます。次に、アプリの表示が更新されて新しい波形が可視化されます。

How a user interaction is processed in the App Designer code and the Pulse class

最終的なアプリを表示して実行する方法については、クラスにデータを保存するパルス発生器アプリを参照してください。

App Designer アプリを開く

次のコマンドを実行して PulseGenerator アプリの作業コピーを開きます。

openExample('matlab/PulseGeneratorAppExample')
このアプリをアプリ コードを変更して再編成する開始点として使用します。

アプリ データを管理する MATLAB クラスの作成

アプリのインターフェイスに依存しないデータとアルゴリズムを分離すると、コードで実行されるさまざまなタスクを整理して、これらのタスクをそれぞれ単独でテストおよび再利用できます。アプリのこの部分を MATLAB クラスとして実装すると、次の利点があります。

  • オブジェクト指向の設計を使用して、相互依存する大量のデータを管理できます。

  • App Designer アプリ内でこのデータを簡単に共有および更新できます。

MATLAB でのオブジェクト指向設計の利点の詳細については、オブジェクト指向の設計を使用する理由を参照してください。

クラスの定義

アプリの中でクラスとして分離すべき部分を判別するには、アプリ コードのうちアプリのユーザー インターフェイスに直接影響しない部分、および実行中のアプリとは別にテストする必要があるアプリの部分を検討します。

パルス発生器アプリでは、アプリ データはユーザーが可視化するパルスで構成されています。Pulse.m という名前の新しいクラス ファイルを PulseGenerator.mlapp アプリ ファイルと同じフォルダーに作成します。classdef ブロックを作成して、Pulse という名前のハンドル クラスを定義します。

classdef Pulse < handle
% ...
end

classdef ブロック内に、アプリ データを保存し、アプリのアルゴリズムを実装する関数を記述します。

プロパティの作成

アプリ データを保存および共有するには、プロパティを使用します。プロパティを定義するには、properties ブロックを作成します。アプリがアクセスする必要のあるデータ用のプロパティと、アプリに関連付けられているアルゴリズムで処理されるデータ用のプロパティを作成します。

Pulse クラスで、パルス タイプ、パルスの周波数、パルスの長さなど、パルスを定義するデータを保持する properties ブロックを作成します。

    properties
        Type
        Frequency
        Length
        Edge 
        Window
        Modulation
        LowPass
        HighPass
        Dispersion
    end

    properties (Constant)
        StartFrequency = 10;
        StopFrequency = 20;
    end

クラスでのプロパティの定義の詳細については、プロパティ構文を参照してください。

関数の作成

クラス定義の methods ブロック内でアプリ データを操作する関数を定義します。

たとえば、App Designer で定義された generatePulse という名前の関数が元の PulseGenerator アプリに含まれており、その関数はパルスのプロパティに基づいてパルスを計算するとします。このアルゴリズムはアプリの表示を更新したり、ユーザー操作に直接応答したりする必要がないので、関数定義を App Designer から Pulse クラスに移動できます。

methods ブロックを作成し、generatePulse の関数定義をブロックにコピーします。クラス定義をアプリから独立した状態に保つには、代わりに、obj.Property 構文を使用して Pulse オブジェクトのプロパティ値をクエリするように、アプリの UI コンポーネント値への参照を更新します。関数定義の先頭は次のようになります。

    methods
        function result = generatePulse(obj)
            
            type = obj.Type;
            frequency = obj.Frequency;
            signalLength = obj.Length;
            edge = obj.Edge;
            window = obj.Window;
            modulation = obj.Modulation;
            lowpass = obj.LowPass;
            highpass = obj.HighPass;
            dispersion = obj.Dispersion;
            
            startFrequency = obj.StartFrequency;
            stopFrequency = obj.StopFrequency;
            
            t = -signalLength/2:1/frequency:signalLength/2;
            sig = (signalLength/(8*edge))^2;
            
            switch type
               % The rest of the code is the same as the original
               % function in the PulseGenerator app.
               % ...
        end
    end

完全な関数コードを確認するには、クラスにデータを保存するパルス発生器アプリを参照してください。

クラス メソッドの作成の詳細については、メソッドの構文を参照してください。

アルゴリズムのテスト

アプリ データをクラスに保存する利点の 1 つは、実行中のアプリとは別個に、データ オブジェクトの操作やアルゴリズムのテストができることです。

たとえば、Pulse オブジェクトを作成し、コマンド ウィンドウでそのプロパティを設定します。

p = Pulse;
p.Type = 'gaussian';
p.Frequency = 500;
p.Length = 2;
p.Edge = 1;
p.Window = 0;
p.Modulation = 0;
p.LowPass = 0.4;
p.HighPass = 0;
p.Dispersion = 0;

Pulse オブジェクト pgeneratePulse メソッドを呼び出します。プロットでパルスを可視化します。

step = 1/p.Frequency;
xlim = p.Length/2;
x = -xlim:step:xlim;
y = generatePulse(p);
plot(x,y);

Plot of a Gaussian pulse

テスト フレームワークを使用してアルゴリズムをテストすることもできます。詳細については、ユニット テストを記述する方法を参照してください。

アプリでのデータの共有

App Designer 内からデータ オブジェクトにアクセスするには、App Designer のコードでクラスのインスタンスを作成し、アプリのプロパティにそのインスタンスを保存します。データを保存したり、ユーザーの操作に反応してクラス関数を呼び出してデータを処理したりする、オブジェクト プロパティを設定およびクエリできます。

App Designer 内の PulseGenerator アプリで、[エディター] タブの [プロパティ] ボタン をクリックして新しいプライベート プロパティを作成します。Pulse オブジェクトを保持する、PulseObject という名前のプライベート プロパティを追加します。

次に、アプリの StartupFcn で、関数定義の先頭に次のコードを追加して Pulse オブジェクトを作成します。

app.PulseObject = Pulse;

ユーザーがアプリでコントロールのいずれかを操作したときに可視化用のパルスを生成するには、関数 updatePlot を変更します。この関数は、ユーザーがアプリでコントロールのいずれかを操作するたびに PulseGenerator アプリの複数のコールバック関数で呼び出されます。

関数 updatePlot で、最初に次のコードを関数の先頭に追加して、アプリ コントロールの値を使用して app.Pulse オブジェクトのプロパティを設定します。

app.PulseObject.Type = app.TypeDropDown.Value;
app.PulseObject.Frequency = app.FrequencyEditField.Value;
app.PulseObject.Length = app.SignalLengthsEditField.Value;
app.PulseObject.Edge = app.EdgeKnob.Value;
app.PulseObject.Window = app.WindowKnob.Value;  
app.PulseObject.Modulation = str2double(app.ModulationKnob.Value);
app.PulseObject.LowPass = app.LowPassKnob.Value;
app.PulseObject.HighPass = app.HighPassKnob.Value;
app.PulseObject.Dispersion = str2double(app.DispersionKnob.Value);

次に、入力引数を app.PulseObject に置き換えて、関数 generatePulse の呼び出しを更新します。

p = generatePulse(app.PulseObject);

最後に、App Designer で定義された関数 generatePulse を削除して、アプリが Pulse クラスで新しく定義された関数 generatePulse を呼び出すことを確認します。

完全なアプリ コードを確認するには、クラスにデータを保存するパルス発生器アプリを参照してください。

クラスにデータを保存するパルス発生器アプリ

この例は、アプリのデータとアルゴリズムが Pulse クラスに個別に実装されている最終的な PulseGenerator アプリを示しています。App Designer で [実行] ボタンをクリックして例を実行します。

関連するトピック