面向对象编程中,这个结构应该如何设计?

4
我有一个UIImageView,通过touchesMoved可以绕其中心旋转。
目前所有代码都在我的ViewController中,检测触摸、计算和跟踪当前旋转、图像本身以及图像的实际旋转。
但现在我想整理一下并做到规范化。我创建了一个名为“Spinner”的新类,它可以跟踪自己的图像和角度属性...
但这应该是一个具有UIImageView属性的NSObject,还是一个实际的UIImageView本身?触摸应该如何处理,ViewController需要参与还是对象可以自行跟踪触摸?
-
编辑:仍然希望得到关于这个老问题的明确答案。
UIControl子类可能在我的Spinner只是一个抽象图像旋转和响应触摸时有意义。
但当它更加复杂,并且有位置、速度、需要与其他对象互动、在多次启动之间持久存在(NSManagedObject子类?)等需求时,触摸和图像只成为整个过程中的一小部分。这就是我认为UIImage只是对象的另一个属性的原因。
以一个简单的例子来说明,在一个盒子里反弹的一堆球。它们需要从边缘反弹,彼此弹开,旋转,响应重力,被触摸时响应-并在多次启动之间保持存在。
因此,从概念上讲,如何在OOP中构建这个结构?

2
听起来 UIControl 应该是最合适的父类,但如果你想要得到有建设性的建议,你需要更详细地解释一下你希望程序员和最终用户如何使用它以及图像来自何处。 - rob mayoff
Spinner是我的“模型”的一部分,不是吗?MVC不意味着我的模型不应该是UIView子类吗? - trapper
3个回答

3
您应该使用UIControl作为父类,并添加UIImageView属性作为子视图。 UIControl有可以重写以跟踪触摸的方法。

我也会选择这种方式。你可以通过一个类轻松设置可用的事件和配置。 - DBD

0

你在寻求“正确的方式”,好像在面向对象编程中只有一个正确答案。

实际上,没有一个正确的设计。它与你期望代码在未来如何扩展和重用有关。

如果你真的想为每一个可想象的扩展做好准备,那么你最终会得到一个非常复杂的设计,但仍然无法涵盖所有情况。

以你的例子为例:从一个触摸控制的旋转器到成为二维物理模拟的一部分……这是一个很长的跳跃。我为什么要用一个通用基类来实现它呢?

  • 如果你只是想要一个“屏幕上可以旋转的东西”的基类……我会说这太泛泛了。没有足够的附加价值来证明需要一个新的类:UIView已经可以实现。

  • 如果你的原始对象意图获得用户输入,那么坚持 iOS 的设计模式并继承 UIControl。

  • 如果你预想一个物理模拟。那么你可能有一个完整的类结构,独立于其如何显示在屏幕上:

一个刚体类,用于描述每个对象(可能是一个类树)的机械属性(形状、重量等)。可以使用单独的委托来进行碰撞检测。 一个刚体状态类,用于描述刚体的位置和速度。 一个刚体模拟器类,拥有一组刚体和每个刚体的刚体状态。 一个刚体视图控制器类,可以为给定的刚体创建一个UIView(可能是UIImageView),并可以调整其大小和位置(根据给定的刚体状态)。 ... 大致就是这样。

不要太担心我的第一个例子,因为那是在我开始更详细地思考之前。物理模拟类型的场景听起来更像是我目前所处的阶段。 - trapper
好的,在那种情况下,这不是一个很好的问题 :-/。无论如何,我稍微编辑了我的答案。 - Kris Van Bael
我还是不太明白,哈哈,但我认为你的回答是最好的。 - trapper
需要详细说明哪个部分吗? - Kris Van Bael

0
我有一个与此非常相似的对象。我称之为MBlob,代表MediaBlob。它知道如何执行各种操作,例如如何将自己分割成两个部分,与另一个MBlob结合(根据形状适当调整大小),等等。它还知道如何生成一个WebView(加载URL),进行调整大小(例如旋转、手势)等等。对于制作小应用程序来说,这是非常方便的类,我认为许多开发人员都有类似的东西。我的应用商店应用程序QCount(免费)和QPlus中也使用了类似的类。
一种构建这样的对象的方法是将其作为NSObject的子类,然后挂接一些协议以使用内置项目。例如,我的接口看起来像这样:
@interface MBlob : NSObject <UIWebViewDelegate, UIPopoverControllerDelegate> {
    id _delegate;
}

所有属性都在.m文件中实现为@synthesize varName = _varName。
然后,您可以从此项连接各种视图。这可能有些过度,但是我的MBlob甚至知道如何启动首选项编辑器以编辑自己的首选项,而不会影响拥有VC。这里有一些值得思考的内容:
@property (nonatomic, strong) UIView* preview;
@property (nonatomic, strong) UIView* displayView;
@property (nonatomic, strong) UIWebView* webView;
@property (nonatomic, strong) UIToolbar* toolbar;
@property (nonatomic, strong) UIActivityIndicatorView* activityIndicator;
@property (nonatomic, strong) NSTimer* timer;
@property (nonatomic, strong) NSString* mediaType;
@property (nonatomic, strong) NSString* mediaValue;
@property (nonatomic) CGFloat   aspectRatio; // width:height
@property (nonatomic) BOOL      aspectRatioLocked; 
@property (nonatomic) CGSize    nativeSize;
@property (nonatomic) CGPoint   nativeLocation;
@property (nonatomic, strong) NSString* title;
@property (nonatomic, strong) UITextField* titleTextField;
@property (nonatomic, strong) UIFont* font;
@property (nonatomic) BOOL fullScreen;
@property (nonatomic, strong) WebviewButtonPreferences* webviewButtonPreferences;
@property (nonatomic, strong) PreferencesEditorViewController* preferencesEditorVC;

我的一个警告是,苹果通过内置类使许多事情变得容易,所以不要过度使用。例如,在上面的代码中,我真的需要字体吗?我不知道,这对我来说不是活动代码,但它是您正在描述的对象类型的示例。如果您将添加更多功能,请使用NSObject的伞形子类,并使您想要使用的任何其他类成为属性。

祝你好运,

Damien


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接