封装不封装,这是个问题。
今天我在看Cocoa开发者邮件列表的时候,看到一个帖子,求助如何在两个View之间互相通信的问题。做Windows程序员的时间长的我都不好意思说了,我意识到,这个问题在我刚刚接触到Mac上的Objective-C时也遇到过。
我现在可以提出这个问题的简化版:“我有一个对话框,获取了一些用户输入的数据。我现在需要从我那个对话框中把这个数据提取出来以供主窗口使用。如何才能从主窗口获取到对话框里的数据呢?”

在 Windows里,尤其是C# .NET,你可以通过添加一个Form对象来创建新的窗口,而且还可以简单地在设计窗口中添加一些不同的“控件”。这些操作是非常容易的。不过一旦窗口创 建好之后,你需要在主窗口的代码中建立刚才新建的窗口的实例,然后提供公共变量在两个窗口之间设置或者获取数据。窗口类是由Windows Form模板写好直接交给你使用的,这当然可以使代码看起来清晰干净,但是它打破了MVC的惯例,所以大部分Windows的程序员会花费不少时间提升他 们思考的方式也就不足为奇了。
我用VS2008做了一个demo程序,截图大概是这样的:
看一下主窗口的代码:
  1. public partial class Form1 : Form
  2. {
  3. Panel p;
  4. ?
  5. public Form1()
  6. {
  7. InitializeComponent();
  8. p = new Panel();
  9. p.Show();
  10. }
  11. ?
  12. private void btnChangeText_Click(object sender, EventArgs e)
  13. {
  14. p.OutputText = this.tbInputText.Text;
  15. }
  16. }
注意看我声明了一个Panel的对象,这是我们需要在上面设置文字的第二个窗口(view)。下面是Panel类的代码:
  1. public partial class Panel : Form
  2. {
  3. public Panel()
  4. {
  5. InitializeComponent();
  6. }
  7. ?
  8. public string OutputText
  9. {
  10. set
  11. {
  12. this.tbOutputText.Text = value;
  13. }
  14. }
  15. }
好,代码很容易理解,但是从这里就可以看出我的观点:MVC模型已经被破坏了。虽然这个例子里面并没有任何编程逻辑,不过很清楚的是这样的设计导致你只需要把代码放到按钮的事件处理里面就可以了,而不是去将逻辑抽象到controller对象中。
你 也许会问,我在C#中如何做MVC呢?呃……这是一个关于Objective-C、Cocoa编程的网站,对于读者们来说这是个作业了……不过坦 白讲,我可不知道。我知道那是一件可能的事情,不过C#语言的内部就没有把开发者向这个方向去引导。我也看过一些讲这方面事情的文章,不过那些也都是基本 上困难到没法实践的。有几篇号称是MVC不过根本不算,所以如果你真想在C#上面实现MVC,自己想办法弄吧……^o^ 我想说的其实就是要想在C#上面实现MVC,那算你狠。
Objective-C/Cocoa的方式
在 Objective-C里,你必须明确地创建一个controller用来处理model和view之间的变化。其实MVC应该被称做MCV,因 为controller是在model和view之间的一个协调员。如果你的model发生了改变,你的controller会通知view。如果用户在 view中做出了某种改变,controller就会通知model。所以我建议初学者可以叫它MCV,会更加形象一点。有点跑题了。
在 Objective-C/Cocoa的世界里,我们建立的controller通常是指应用程序(Application)的托管 (Delegate),或者可以简单称做app delegate。很多Windows程序员都会在这里迷惑不解的事情是,我们通常学习到的面向对象开发就是你应该去做的事情,而并不会关注为什么你会去 做,或者你为什么不去做。我并不是说你别用OOP的思想,而正相反我建议去用。问题是如果把一切都抽象化,那就有点太傻叉了……我们应该有很好的理由去写 这些代码,而不要用诸如“我从大学里面学的……”或是“我一直就这么干……”这种理由。
当你在Objective-C里面建立一个app delegate的时候,这个delegate可以做为你所有model和view的controller,或者你也可以为不同的model和view分 别创建controller。想怎么干就怎么干吧。不过有一个比较重要的事情是要记住的,如果你把所有的代码都扔到同一个app delegate类里头,那你就有了一个超大的app delegate文件,很难看清楚。
一些例子程序
为了 帮助那个提出问题的朋友,还有另外一些想从Windows开发转变到Cocoa开发的朋友们,我也写了点简单例子来帮助把这个问题变简单。如果 你想让两个View,或者两个窗口可以互相之间通信,只要在他们之间传递消息就可以了。虽然把你的view们封装到它们自己的类中并不是坏事,不过通常来 说真的没必要。在任何一种语言和任何一种平台上,都有实现这个功能的方法,所以就别管我没提到的事情了,我也没说这是唯一的方法不是……我说的方法是简单 直接的方法,可以帮你更快的理解。
我同样建了一个简单的demo程序来演示上面说的,这里是截图:
你可以在这里下载例子。
这里是我提到的代码,只需要在app delegate的头文件中将你的view声明为outlet:
  1. @interface AppDelegate : NSObject {
  2. IBOutlet NSTextField *inputText;
  3. IBOutlet NSTextField *outputText;
  4. }
然后声明这样一个方法,在按下按钮之后会执行:
  1. - (IBAction)updateText:(id)sender;
最好要做的事情就是在IB里面把action和outlet连到AppDelegate对象上,任务完成。就这么简单。
为什么Windows的方法烂,Mac的方法赞
好吧,这个小标题仅仅是个玩笑,Windows专家们千万表喷俺。不过我的确认为C#设计用户界面的方式会把人们的代码搞得贼乱,而且明显不是MVC模式。
当 然,又来了,怎么做还是看你自己,不过.NET的用户界面设计工具非常鼓励用户去破坏MVC模式。当你在设计器里面把一个按钮拽到窗口里,然后双 击那个按钮的时候,它就自动地给你指到按钮点击事件代码里,大部分程序员就自然而然地在那里写代码了。当你在设计过程的时候,倒也没什么,不过它根本没有 做什么来支持你将逻辑和表现分开。
在Objective-C里,想破坏MVC设计模式倒是很困难的事情。基本上你都必须遵循这个模式。甚 至当你使用Interface Builder在app delegate和action及outlet中间建立连接的时候,都会带有一个可视的MVC表现。要连接app delegate类(你的controller)到outlet的时候(比如输入框),你按住ctrl之后从AppDelegate拖拽一根线放到 outlet上。当你想告诉AppDelegate执行一些动作,你要从触发动作的对象中拽到AppDelegate对象上。反过来是不行的。养成这样的 习惯其实很好,只不过Windows的铁杆程序员会相当不习惯。
结论
从Windows程序员转到Mac程序员是有一点挑战的,不过你越早抛掉从前的开发的概念,就越容易接受Mac开发的概念。想想令狐冲吧……Mac的开发的确是不太一样的。要习惯这种开发思路,而不要试图沿用从前的习惯来进行Mac开发。
承 认这一点吧兄弟们,工程师们都是很傲慢的,而且当学习一门新的语言、技术或是平台的时候,通常会认为他们已经很清楚了。最后这句的英文真的很棒, 我不知道怎么翻译才能完美的表达这句话,和大家共勉:Goto is not inherently evil, you know? Until next time.
转自iOS分享网--http://iosshare.cn

Cocoa教学:Windows OOP与Cocoa MVC之对比相关推荐

  1. Windows文件夹、文件源代码对比工具--WinMerge

    /*********************************************************************** Windows文件夹.文件源代码对比工具--WinMe ...

  2. **Django介绍 和 MVT 模式 MVC 模式对比**

    1. 简介 Django,发音为[`dʒæŋɡəʊ],是用python语言写的开源web开发框架,并遵循MVC设计.劳伦斯出版集团为了开发以新闻内容为主的网站,而开发出来了这个框架,于2005年7月在 ...

  3. windows server 2008版本介绍与对比

    windows server 2008版本介绍与对比 Windows Server 2008系统推出众多版本:Web版.标准版.企业版.数据中心版.IA64位版等等.只有了解 Windows Serv ...

  4. 多款优秀的 JS MVC 框架对比

    2019独角兽企业重金招聘Python工程师标准>>> 正如之前说的,产品生产有功能时代转入体验时代,产品为王,体验为王,已经是时代趋势.体验经济的到来,说明前端的技术要求越来越高, ...

  5. Linux与Windows中动态链接库的分析与对比

    摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系 ...

  6. windowslinux服务器性能对比,Windows/Linux服务器的选择与对比

    对于服务器是选择Windows系统好还是Linux系统好,这样一个话题实际上网上有很多文章在探讨.我们也都一致的认可Linux系统的性能要优于Windows系统,而Windows系统则相对更简单易于使 ...

  7. 【facenet】快速复现 实现 facenet-pytorch 人脸识别 windows上 使用cpu实现 人脸对比

    目录 0 前言 1 搭建环境与项目 2 人脸预测与结果展示 0 前言 这一次要复现的是人脸识别中的 facenet-pytorch 参考了: Pytorch 搭建自己的Facenet人脸识别网络(Bu ...

  8. Windows Azure Pack与VMware VRA 对比(二)安装VRA IaaS服务器

    IaaS服务器主要提供web portal 的访问,工作流的处理等.这个服务要装在Windows server 2012 R2服务器上,前提条件比较多,安装过程中容易失败.首先通过访问https:// ...

  9. Windows Azure Pack与VMware VRA 对比(五)Azure Pack 安装及IaaS功能测试

    Windows Azure Pack 是无额外成本向 Microsoft 客户提供的 Microsoft Azure 技术集合.它与 Windows Server.System Center 和 SQ ...

最新文章

  1. Makefile文件的使用
  2. Python 常用函数 configparser模块
  3. Android Studio如何减小APK体积
  4. mybatis 自动填充无效_开发小知识-mybatis-plus自动填充与读写分离
  5. 一文读懂深度学习:从神经元到BERT
  6. java 序列化声明_显式声明默认Java类序列化方法的原因是什么?
  7. 计算机组成原理平均cpi怎么算_2020考研 | 计算机统考408院校盘点,408考试内容难易分析...
  8. Django环境搭建及学前准备
  9. 一个完整的汇编程序结构
  10. 【游戏】基于matlab GUI时钟设计【含Matlab源码 1102期】
  11. Selenium认识与实战(学习版)
  12. 数据库课程设计——某工厂的物料管理系统(附Java源码与课程设计报告)
  13. 一颗椰子糖机器人_一颗椰子糖的热量
  14. wating for network configuration unity恢复
  15. Nature Aging | 复旦大学冯建峰/程炜揭示每晚睡7小时刚刚好,睡过多或过少都有损大脑和心理健康...
  16. 计算机网络学习-应用层笔记
  17. 将Eclipse设置为中文
  18. 原创 基于MC3362D的十米波段语音收发机电路图
  19. 狗日的腾讯与骡子日的360
  20. java is命名_JAVA命名规范性总结

热门文章

  1. JS闭包中未使用的引用变量回收机制浅探
  2. 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)...
  3. Python3中的魔术方法汇总
  4. K210系列开发板介绍
  5. 使用Typora绘制流程图
  6. python3 安装PIL
  7. 计算机科学技术考研内容,计算机科学技术考研考什么科目
  8. 爆炸性环境设备通用要求标准_防爆电气设备的适用环境及温度要求
  9. 怎么用计算机技术预测蛋白质结构,蛋白质结构预测及方法介绍 一搜索无重复 - 生物科学 - 小木虫 - 学术 科研 互动社区...
  10. java字符串转字符串数组_Java字符串数组到字符串