0

私は、人々のチームが使用する開発用のプラットフォームを設計しています。このチームは、開発者とユーザーの両方を代表しています。彼らは両方とも、現実世界のアクションにプラットフォームを使用し、プラットフォーム用の新しいコードを開発します。私は MATLAB のオブジェクト指向プログラミングと、バージョン管理に Subversion を使用しています。私の問題は次のとおりです。

  1. カプセル化を維持し、システムのモジュールを維持するために、パブリック インターフェイスを最小限に抑えたいと考えています。関連するクラスメンバーのみを公開することでこれを行います。

  2. 複雑なプロセスが失敗した場合、特にプライベート クラス メンバーが原因で失敗した場合は、その理由が明らかでない場合があります。障害点が発生するまでに 1 時間以上かかった場合、何が起こっているのかを調べるために、開発者やユーザーがブレークポイントを使用してコードを再実行する必要はありません。

  3. 開発者がプライベート クラス メンバーを含む新しいアイデアを試したい場合、ソフトウェアのブランチをチェックアウトして好きなことを行うことができますが、これには時間と計画が必要です。「実行時」にできることではありません。

  4. 開発者とユーザーが動的にアクセスできるようにするバックドアを介して、一時的にプライベート クラス メンバーにアクセスする方法が必要です。

この質問は、私の一部のナイーブから生じている可能性があります。私はソフトウェア エンジニアではありません。チームで最も経験豊富なプログラマーです。したがって、これを行うべきではない理由も探しています。この問題について考えるより良い方法はありますか?

classdef DevTest

    properties (Access = private)
        privateProp = 'This property is private';
    end

    methods (Access = private)
        function privateMethod(This)
            disp('You''ve gained access to a private method!')
        end
    end

end
4

2 に答える 2

1

これが私の考えです。オブジェクトをプロパティとしてDeveloper含むクラスを作成します。Developable呼び出されるインターフェイスには、 、、およびDevelopableの 3 つの抽象メソッドがあります。これらのメソッドへのアクセスをおよびに制限します。以下にサンプルコードを示します。getPropertysetPropertymevalDevelopableDeveloper

classdefためのDevelopable

classdef (Abstract) Developable < handle

    methods (Abstract, Access = {?Developable, ?Developer})
        propVal = getProperty(This, propName)

        This = setProperty(This, propName, propVal)

        varargout = meval(This, methodName, varargin)
    end

end

そしてDeveloper

classdef Developer < handle

    properties
        DevObj@Developable
    end

    methods
        function This = Developer(DevObj)
            if isa(DevObj, 'Developable')
                This.DevObj = DevObj;
                warnId = '''Developer:debugUseOnly''';
                warnMessage = ['''The Developer class should only be used ' ...
                    'temporarily to gain access to private and ' ...
                    'protected class members. Do not use in any ' ...
                    'permanent manner. Instead contact the owner ' ...
                    'of the class you wish to modify, and work out a ' ...
                    'solution.'''];
                warnStr = ['warning(' warnId ',' warnMessage ')'];
                evalin('caller', warnStr)
            else
                errorId = 'Developer:nonDevelopableObject';
                errorMsg = 'DevObj must be a Developable Object';
                error(errorId, errorMsg)
            end
        end

        function propVal = getProperty(This, propName)
            propVal = This.DevObj.getProperty(propName);
        end

        function setProperty(This, propName, propVal)
            This.DevObj.setProperty(propName, propVal);
        end

        function varargout = meval(This, methodName, varargin)
            if nargout > 0
                out = cell(1, nargout);
                [out{:}] = This.DevObj.meval(methodName, varargin{:});
                varargout = out;
            else
                This.DevObj.meval(methodName, varargin{:});
            end
        end

    end

end

これは私にとってはうまくいくようですが、いくつかの問題があります。

  • すべてのサブクラスは の 3 つのメソッドを実装する必要Developableがありますが、これらのメソッドに含まれるコードはすべてのインスタンスでほとんど同じです。

  • クラスから継承し始めるDevelopableと、物事は複雑になり始めます。

  • これを使用して静的メソッドにアクセスする方法がわかりません。

私の問題を解決する、または上に挙げた問題のいくつかに対処するためのより良い方法を誰かが持っていますか?

Developableクラスの例を次に示します。

classdef DevTest < Developable

    properties (Access = private)
        privateProp = 'This property is private';
    end

    methods (Access = private)
        function privateMethod(This)
            disp('You''ve gained access to a private method!')
        end
    end

    methods (Access = {?Developable, ?Developer})
        function propVal = getProperty(This, propName)
            propVal = This.(propName);
        end

        function This = setProperty(This, propName, propVal)
            This.(propName) = propVal;
        end

        function varargout = meval(This, methodName, varargin)
            if nargout > 0
                varargout = cell(nargout, 1);
                [varargout{:}] = This.(methodName)(varargin{:});
            else
                This.(methodName)(varargin{:});
            end
        end
    end
end
于 2013-05-10T19:30:59.723 に答える