2013-05-10 71 views
0

我正在設計一個人員將使用的開發平臺。這個團隊代表了開發者和用戶。他們都將使用該平臺進行實際操作,併爲該平臺開發新代碼。我正在使用MATLAB的面向對象編程和Subversion進行版本控制。我的問題如下:MATLAB:動態訪問私人班級成員

  1. 我想保持公共接口的最低限度,以保持封裝並保持系統模塊化。我只會讓相關的班級成員公開。

  2. 如果一些複雜的過程失敗了,可能並不明顯,尤其是如果它由於私人類成員而失敗的話。如果在故障點之前花費了一個小時或更多時間,我不希望開發人員/用戶不得不重新運行代碼以找出發生了什麼事情。

  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 
+1

我很努力地看到這一點,在這裏......如果您打算編寫代碼來打破MATLAB的OO範例,那麼爲什麼還要麻煩編寫OO代碼?聽起來像是給我帶來麻煩......也許如果你對最終目標提供了一個不太抽象的描述,那麼可能會更容易幫助你想出一個有形的設計。 – wakjah 2013-05-11 09:33:22

回答

1

克里斯,請不要這樣做 - 這是一個非常糟糕的主意,它不會讓生活更容易爲您或您的開發人員。

如果您正在爲其他開發人員設計純粹的東西,請相信他們能夠進行更改並且不會搞砸。如果您正在爲用戶設計一些東西,請將其鎖定,以便僅提供他們所需的東西。

如果你正在和一個開發團隊一起爲用戶設計一些東西,那麼我希望你使用的是版本控制系統,對不對?

如果沒有,則立即停止所有工作,將其加入到版本控制中,並開始使用它。

保持主幹鎖定爲用戶,方法和屬性爲私人適當的。如果你的開發人員希望通過公開的方式嘗試某些事情,他們可以檢查一個私人分支並儘可能多地進行更改,而不必擔心他們會「忘記將其改回」(該短語響起了警鐘對我來說,讓我覺得你可能沒有使用版本控制)。如果他們的實驗證明有用,並且您可以證明爲用戶公開某些方法或屬性,則將其更改合併回主幹。

PS如果你真的想追求你的設計,你可以考慮讓你的開發者方法Hidden,以便其他用戶不能看到祕密後門。

+0

謝謝你的迴應,山姆。我們正在使用版本控制,但您的觀點是很好的。 – hoogamaphone 2013-05-13 15:55:52

+0

薩姆,我澄清了我的問題。它以任何方式改變你的答案嗎? – hoogamaphone 2013-05-15 12:36:52

+1

我認爲這是一個很好的說明,但我不認爲我的答案有很大改變。我仍然會建議你,雖然1是一個好主意,但4是一個好主意。 2是一個常見問題,可以通過良好的調試實踐來解決(例如,您可以實現一個記錄器類,具有不同的日誌記錄級別以進行調試和定期運行 - Google log4m爲MATLABCentral上的示例)。我仍然不確定3的問題 - 是否需要大量的時間和計劃來創建和檢查開發分支? – 2013-05-15 12:52:41

0

這是我的想法。我將創建一個名爲Developer的類,該類將包含一個Developable對象作爲屬性。稱爲Developable的接口將具有3個抽象方法,getProperty,setPropertymeval。我將限制訪問這些方法DevelopableDeveloper。這裏有以下一些示例代碼:

classdefDevelopable

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 
     [email protected] 
    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 

這似乎爲我工作,但也有一些問題吧:

  • 每個子類都必須imp請注意0​​中的三種方法,但這些方法中包含的代碼在每個實例中都幾乎相同。

  • 一旦我開始繼承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