我经常读到有关将大型(单片?)应用程序代码块拆分为单独的源代码文件以使其更易于维护等的可取性,但我还没有看到任何解释确切如何做的事情此
在添加课程的子类时,创建单独文件的过程非常简单 - 这是我正在尝试实现的一个很好的例子 - 但是如果我们只有一个控制器对象并且我们想分割我们的代码说,(1)一个接口和实现文件组包含仅计算事物的方法和(2)另一对包含仅打印相关的方法,但每个方法都有能够访问所有其他方法,就好像它们都在一个(源)文件中一样。
有关如何解决这个问题的详细建议(如果可能的话)将不胜感激。谢谢: - )
答案 0 :(得分:3)
最好通过使用类别来完成。例如,创建一个名为MyController + Printing.h的头文件:
#import "MyController.h"
@interface MyController (PrintingSupport)
- (void)print:(id)sender;
@end
和实现文件MyController + Printing.m:
#import "MyController+Printing.h"
@implementation MyController (PrintingSupport)
- (void)print:(id)sender
{
}
@end
查看Apple的头文件,了解这项技术的很好的例子。
答案 1 :(得分:2)
如果您的课程增长如此之大,您正在考虑如何将它们分成单独的源文件,您可能会遇到设计问题。
模型 - 视图 - 控制器(更好的,模型 - 控制器 - 视图)设计模式几乎自动创建小型模块化代码。
模型处理与数据相关的所有内容。视图管理实际的可视UI,控制器将两者粘合在一起。每个都是一个单独的类,理想情况下,模型和视图应该是独立的,以便它们可以轻松插入另一个应用程序。
关键是在分离功能方面完全无情。将数据停放在控制器中总是很诱人。当你只是用很少的数据学习和编写小程序时尤其如此。但是,随着数据复杂性的增加,您的控制器很快就会爆炸性地复杂化。
所有优秀的设计都从数据模型开始。模型应该处理数据中的所有逻辑关系,即创建,修改,验证,保存等。正确设计的数据模型对UI完全不可知。理想情况下,数据模型应与标准视图,Web视图,命令行或转储URL一起使用。
我总是通过在绝对最小界面的测试应用程序中创建数据模型来启动项目。 (通常它只是一个空白的应用程序启动,以编程方式操作数据模型,打印到控制台并退出。)只有当数据模型独立工作时,我才转向程序的其余部分。
现在我了解了数据和数据操作,我可以为我将要运行的每个环境设计一个UI。 UI仅了解如何创建UI元素以及如何响应事件。它不包含任何数据,甚至不包含将元素相互关联的逻辑。
控制器将视图和数据模型粘合在一起。控制器仅知道将哪些消息发送到数据模型以获得响应于特定事件而进入特定UI元素的数据。它不验证数据或对其执行任何逻辑操作。它只是在数据模型和当下视图之间路由信息。
创建另一个接口的任何操作(如打印)都应该有自己的控制器对象。例如,在打印时,只有数据模型才能理解所有数据如何在页面上组合在一起。控制UI视图的同一控制器没有理由控制打印。相反,打印控制器只是询问数据模型以打印数据。 UI控制器只需调用打印控制器并将其指向用户选择的数据即可。
在您的特定示例中,计算方法将在数据模型中,打印控制器中的打印方法等。使用模型 - 视图 - 控制器,您最终会得到许多令人惊讶的小型模块化类,易于管理,测试和移植。
答案 2 :(得分:1)
我不熟悉这种编程语言,但总的来说,模块化的目的是隐藏复杂的实现并暴露一个简单的接口。这很好,因为您通常不需要所有数据和所有功能来完成每项任务。这是通过将数据保持接近它们使用的位置(例如,同一类)并使用很少的公共方法来完成的。
但是,在某些情况下,您需要支持在模块之间轻松共享大量数据和功能,这听起来就像您想要做的那样。例如。在GUI编程中,模型 - 视图 - 控制器设计模式就是这样。关键是要以其他方式对数据和功能进行分组,但要做得好不容易。
问自己的问题: 不是让控制器与数据分离,而是可以重构,以便数据的每个部分都与控制器的相应部分一起?例如,如果您有两种类型的数据,您可以重构为两个类,每个类都有计算和打印该类型数据的方法吗?也许您还会发现某些“数据”实际上是控制器的状态,这绝对属于控制器代码。