2013-05-10 35 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