Tag: 编程

面向继承,组合或协议

我记得计算机科学课程的第一课Java继承。 🙂 在我们的学校里,我们的程序员受到了教授,面向对象改变了近几十年来开发软件的方式。 继承是最受灌输的概念之一。 基本上,对象的继承是从父对象继承特征的,因此他与兄弟姐妹共享这些特征。 参见示例: 问题是要知道使用哪个对象“孙子”来实现,但是这个主题很广泛,在这里可以得到最好的解释: 多重继承 多重继承是某些面向对象的计算机编程语言的功能,其中对象或类… en.wikipedia.org 协议是多重继承吗? 不,对不起。 对不起, 协议(或接口)实际上是多重继承的致命解决方案,因为它定义了对象的行为,但是实现仅在类中进行。 使用协议的简单事实不会创建一个合成环境。 但这使我们更加接近多重继承环境。 但是组成是解决方案吗? 当一个类具有另一个类的属性时,就是合成。 就是这么简单,我们每天都在使用这个概念。 因此,关于它的讨论是,我们始终具有明确的定义并限制了OOP概念的组成。此链接清楚地表明: 对象组成 在计算机科学中,对象组合(不要与功能组合相混淆)是一种将简单的组合… en.wikipedia.org Swift中的面向协议(POP)? 移动世界对新概念感到疯狂,所有这些都将使我们通过Swift。 每天我看到人们发布用语言创建的东西。 这是不可思议的,我认为极限是我们的想象力。 但是想象一下,如果不使用属性就可以组成行为,那么行为就构成了对象。 这正是我们通过扩展协议所获得的,这是一种构建灵活的面向对象结构的方法。 关于协议+扩展❤的示例 扩展协议是一种创建合成的方法,在这些情况下无需使用继承。 这足以改变Swift中继承的整个概念,这样我们就可以在不更改可可对象树的情况下插入行为。 在此示例中,很明显,我们的ViewController我的孩子仍然是UIViewController对象。 但是通过协议,我们可以输入默认行为,并可以创建将协议作为继承来接收协议的函数。 通过一定的复杂性,我们可以具有组合的优点,而不会冒产生多重继承复杂性问题的风险。 结论 本文的目的是提醒我们所有人,我们应该始终研究和质疑新技术及其对我们的允许。 我们必须讨论OOP的基本概念,因为它们每天都是软件开发的基础。 功能语言和反应式编程概念正在采用我们的软件,这是我们赖以生存的时刻。 但是最基本的概念变得更加重要,建筑物的基础是最重要的部分。 一篇非常好的文章,讨论了方法和如何帮助选择: 组成与继承:如何选择? 从一开始…………没有继承,也没有组成,只有代码。 而且代码繁琐,重复… www.thoughtworks.com 谢谢,我们将讨论任何事情。 争论是学习。 🙂

如何使您的存储库自述文件看起来不错!

存储库自述文件对我总是很满意。 它们都有不同的风格,包括图像,GIF,徽章,链接等。它们不仅可以看上去,而且可以传达有关该项目进行中的大量信息,并且可以吸引人们的注意力。 可悲的是,我们大多数人,至少在项目开始时,没有浪费时间使我们的回购自述文件大放异彩。 今天,我将向大家展示适合您的回购交易的简便程度,使其看起来比以往更加专业。 免责声明:**这 如果圣诞节和新年前夕之间的一周内上线,则发布。 因此,尽管我可以做一些需要更少时间的事情,但仍然很重要。 继续阅读以了解如何使您的仓库回升。 在..之前很伤心.. =( 您可以在屏幕快照中看到我的Marvels App博客文章存储库的外观。 没有真正的吸引力。 对我而言,这仅是在提醒人们机会不足。 分享有关我的项目和目标的更多信息的机会。 **如果您尚未查看marvel的应用博客文章系列,则可以在这里进行。 您会发现许多有趣的内容,内容涉及如何使用许多不同的pod和工具从头开始创建应用程序,从而使您的生活更轻松。 给我看看更好的.. !! 本自述文件中有几件事正在进行,因此让我介绍一下: 现在它具有徽章,在顶部显示相关信息 它具有锚点导航,允许读者跳至特定部分。 它有一个屏幕截图,显示了应用程序流程以及用户对项目的期望。 它有一个动机部分,回答一些问题,例如: 这是什么? 我为什么要在乎呢? 它与他人有何不同? 这个存储库的目标是什么 ? 它具有发布链接,将链接带到页面。 它具有安装和测试部分,提供有关如何运行这些步骤的说明。 最后但并非最不重要的一个许可证部分,显示代码的可用性 。 这可以像您认为的那样广泛。 您可以使用一些您喜欢的开源项目作为自己存储库的灵感源。 *您可以在这里查看 github上的页面。 自述文件的资源.. 在下面,您可以找到一些资源,这些资源可以在上面提到的仓库转换过程中提供帮助。 去看一下! shields.io是一个了不起的工具。 它允许您粘贴存储库URL,并可以根据您的回购文件推荐徽章。 Shields.io:开源项目的质量元数据徽章 我们提供快速且可扩展的信息图像,作为GitHub,Travis CI,Jenkins,WordPress等的徽章。 Codecov和工作服可以将您的代码覆盖率百分比显示为自定义徽章。 太棒了!! 连续代码覆盖率 连续代码覆盖率。 托管覆盖率报告与GitHub,Bitbucket和GitLab高度集成。 浏览器… codecov.io 工作服 修改说明 coveralls.zendesk.com […]

Swift协议的用法-1

在上一篇文章中,我展示了使用快速扩展名进行打印的更智能方法。 并且在文章中,我敦促如果有人遇到在AnyObject上创建扩展的想法,请告知社区。 但是当我对此进行研究时,我知道这是不可能的。 但是与此同时,我很快遇到了面向协议的编程,我想可以将其用于实现我们的目标之一。 目标:我们需要避免使用与扩展方法po()相同的代码行 喜欢, 现在,使用面向协议的协议,我们可以执行以下操作, 因此,在上述类型的任何对象上都将允许使用po()。 po()的另一个优点是在同名空间中打印字典和数组,即anArrayObj.poa()或anDisctObj.pod() 今天就这些。 尝试以任何可能的方式使用扩展名,不要忘了❤️并发表评论并分享您的想法。 访问我的网站以查看到目前为止我已创建的应用程序http://www.linklyapps.in/

iOSND新闻:核心数据更新

iOSND核心数据课程更新为Swift 4 我很高兴代表整个iOS开发人员纳米学位计划团队,宣布我们核心数据课程的全新版本! 对于任何成功的iOS开发人员而言,核心数据都是一项基本技能,并且本课程将教授所有最佳实践和最新功能。 如果您有一些用Swift编写基于表视图的应用程序的经验,并且对构建可创建或使用内容的应用程序感到兴奋,并且不想让数据管理使您变慢,那么这就是您的选择。 我是第一手知道的,因为我在自己的开发者旅程中发现了Core Data的优点。 我第一次开始学习Core Data,当时正准备参加我的第一次黑客马拉松。 距离我们还有几周的路程,但是我已经知道我想要构建什么应用程序。 这将是一个可视化的日程表应用程序,可以帮助有特殊需要的家庭管理日常工作。 我之所以开发此应用程序感到很兴奋,因为当时我使用了来自职业治疗师的夹层卡片纸和魔术贴工具,很难携带。 我梦想着在手机中将其作为应用程序使用。 当我思考了技能之后,我将需要构建应用程序-设计用户界面,使用收藏集-我意识到我遇到了很大的障碍。 我不知道如何保存应用程序的数据。 我非常确定我可以招募队友在UI方面提供帮助,但是我认为我不能指望找到一个了解iOS持久性的人。 我本人必须自己学习。 老实说,我对使用关系数据库的前景并不感到兴奋。 我早在几年前的Web编程课程中就遇到了它们,而管理表和唯一标识符的细节并不能完全吸引我的兴趣。 因此,我很不高兴地在Core Data上寻找了资源,我听说这是Apple处理持久性的方法。 我找到了我能找到的最平易近人的教程(这是在Objective-C时代开始的),并适应了我所期望的一周无聊的后端工作。 令我惊讶的是,那一周充满了变革和活力。 事实证明,Core Data根本不需要我直接与关系数据库交互! 我了解到,Core Data 管理着数据层 ,使开发人员可以与基础存储区交互,而不必担心其实现细节。 毕竟,我不必成为数据库管理员即可编写我的应用程序! 长话短说,我参加了这次黑客马拉松,与一名设计师和一个UI开发人员合作,亲自编写了数据层和持久性,我们获得了第一名。 感谢核心数据! 从那时起,我一直是Core Data的热情拥护者和老师,是为iOS应用程序开发人员学习的一项非常有用的技能。 因此,您可以想象我很高兴地宣布,今天我们为iOS开发人员Nanodegree计划推出了完全更新的Core Data课程。 我与Udacity iOS工程师Josh Svatek合作构建了本课程。 我们的过程是首先重写现有示例应用程序的代码库,以使用WWDC的最佳实践和最新功能,然后根据该经验构建和编写课程。 我们还试图平衡大多数Core Data文档的大量文本内容。 一开始可能会造成混淆的一件事是使用了许多名称相似的类: NSManagedObjectContext , NSManagedObjectModel , NSPersistentStoreCoordinator , NSPersistentContainer 。 我们决心通过使它们栩栩如生的动画帮助初学者更轻松地区分它们。 我们很高兴与您分享本课程,以帮助那些像过去一样对开发应用感到兴奋的开发人员,并决心不让数据管理成为障碍。 新课程现已作为iOS开发人员纳米学位计划的一部分提供,该课程使您可以访问经过代码审查的项目,并获得个性化的支持和进度反馈。 您还可以在免费版的iOS持久性和核心数据课程中查看新的核心数据课程。

流利的蒸气关系-服务器端Swift

了解如何在模型,父母,孩子和兄弟姐妹之间建立关系。 我们将创建一个小型Web应用程序,了解如何实现Model作为Parent , Children和Siblings之间的关系 。 本文假定您已经对 Vapor 有所了解, 并希望 使用 Fluent 在您的模型之间 建立一些 关系 。 否则,您可以参考 Vapor的Documentation 来设置您的第一个项目 。 列出主人约翰的所有宠物 在第一个教程中,我们将构建一个简单的Web API,以在线添加宠物及其主人信息。 让我们将数据保存到数据库中 ,该数据库可通过路线访问。 我们将通过JSON将数据提供给客户端。 建立关系 关系允许数据库实体之间基于外键的连接。 我们要做的是创建Pet并将其设置为“ Children”作为所有者 。 这样,我们将能够从一个所有者那里获取所有Pet 。 外键 为使魔术发生,我们需要在Pet上添加一个外键 ,该键将是一个Node类型,该类型将存储Parent的ID,即Node。 var owner_id: Node? 并在数据库中建立关系,请将以下行添加到prepare方法中: pets.parent(Owner.self, optional: false) 如果您想迁移数据库,请单击“如何使用Vapor的Fluent迁移数据库”的链接。 最后,您的Pet.swift文件应如下所示: 此外,要建立关系,您需要将所有者的ID设置为宠物的owner_id 。 注意:请记住,实体 所有者 将获得一个 id 在 save() 。 我们知道我们其中一位主人的id为1 ,我们可以设置一条路线来放置Pet […]

让我们做得更好:UITableViewCell

每个iOS开发人员都会创建UITableViewCells,但让我们做得更好。 根据我的实践,这里有五个原则。 TL; DR 在自己的小腿上做; 将用户界面设为私有; 不要配置模型; 让他们暗恋; 重用之前重设。 完整示例应用程序的源代码: https : //github.com/alekseishirokov/medium-01-better-uitableviewcell 每次在情节提要中创建新的UITableViewController时,XCode都会创建一个空单元格原型。 这导致开发人员使用此模板将UI元素直接放置到此单元格视图中。 但这是一个坏习惯。 迟早,您的项目经理会要求您使用完全相同的单元格设计,但要使用另一个表。 当他们告诉我不仅要在人员的详细信息视图中还必须在部门的详细信息视图中显示文档列表时,我已经摆脱了这种行为。 我文档的单元格原型包含10个UILabel,2个UIImageViews和一堆棘手的约束。 尽管XCode具有复制粘贴命令,但这并不容易。 让我们做得更好:在自己的xib文件中创建UITableViewCell并在所需的任何表中重复使用。 这很容易做到。 按Cmd + N创建一个新文件。 然后选择iOS → Cocoa Touch Class 。 然后在下拉菜单的子类中选择UITableViewCell ,输入类名,并选中“ 同时创建XIB文件”复选框。 XCode创建两个文件: DocumentTableViewCell.swift和DocumentTableViewCell.xib 。 使用xib文件将UI元素放入单元格视图中。 使用swift文件将IBOutlet与这些UI元素绑定。 然后,您可以在表视图控制器中使用此DocumentTableViewCell ,如下所示: 这意味着我需要重构每个使用我的DocumentTableViewCell的表视图控制器,如下所示: 如今,我做得更好。 我将UI出口声明为单元格视图专用。 我仅使用configure方法将数据传递给UI元素: 在表视图控制器中,您只需将文档的优先级作为参数传递给configure方法。 直觉是, 优先级是数据,取决于单元格视图如何显示数据。 同样,在单元设计发生更改的情况下,也无需重构表视图控制器。 即使在教程中,也通常通过将模型对象传递给configure方法来用数据填充单元格: 这似乎是一个优雅的解决方案,但事实并非如此。 这会将单元格的视图与模型对象耦合在一起。 单元格视图取决于模型对象的结构。 但是,我们坚持的MVC模式就是将视图和模型分离。 我倾向于将数据作为单独的参数传递给configure方法: […]

依赖注入-什么,为什么和如何?

我们将探索依赖注入,重点是快速的iOS开发,但是这个概念适用于大多数面向对象的语言。 我们还将看到在iOS环境中应用DI的一些实际注意事项。 本文是我深入实施DI并学习各种实践,理论方面的结果。 什么是依赖注入? “依赖注入”是5美分概念的25美元术语”。 是关于DI的经常重复的格言。 从本质上讲,DI意味着尽可能地通过从代码外部提供对象来代替在代码内部创建对象 。 因此,这个词。 构造函数,属性,方法通常是我们创建对象的地方,可以从外部替换。 因此,我们最终得到3种类型的注射。 构造函数注入 资产注入 方法注入 我们将在“如何..?”部分中探讨这三种类型。 为什么要进行依赖注入? 让我们在一个场景的帮助下进行讨论。 场景-Koala Koder! 假设您有一个具有用户登录名的应用程序。 用户模型struct / class封装了登录的用户数据。 假设您是Koala Koder(一个像树袋熊一样懒惰的程序员)。 您也许提出了一个既快速又肮脏的解决方案。 将用户模型存储在NSUserDefaults中,然后通过属性获取它。 众所周知,苹果是如何喜欢单例类的,所以我们遵循它们使UserModel成为单例。 问题,到处都是问题… 1.单元测试员Vader罢工! 一位高级开发人员突然转为阴暗面,开始抱怨单元测试 。 他/她将不允许未经单元测试的应用通过代码审查。 2.出现疯狂的新用例! 如果这还不够,则应该支持一个新的用例 。 我们的应用程序现在应该支持多个用户 。 3.“让我们移动到” 现在,我们还达到了用户默认设置无法扩展的地步,希望迁移到新的数据序列化方法。 现在,甚至UserProfile中的我们的获取器和设置器也不安全。 为什么会有问题? 因此,我们发现自己陷入了严重的麻烦。 让我们分析为什么。 1.单身人士很难测试 现在,如果要对使用此单例的viewcontroller进行单元测试。 在单元测试中,您将创建一个UserProfile对象,手动调用viewDidLoad或其他方法。 现在,您必须验证是否调用了UserModel.sharedInstance.greet() 。 由于UserModel.sharedInstance是不可变的,因此我们不能用扩展UserModel的模拟类替换它,该类将覆盖greetUser并设置一个可以检查的标志。 因此,我们的测试范围下降了。 2.代码约束内部的实例化会产生强烈的耦合,从而产生有害的约束 在我们的方案中,通过使用单例,我们将代码库绑定到单个UserModel,但是现在我们的应用程序需要多个用户模型。 因此,一般而言,使用单例将很难适应新的用例。 您以为单身汉的想法突然不再那么单身了 […]

泛型-我一直看到的“元素”参数是什么? (速记3)

在学习Swift的过程中,我注意到一些函数要求使用Element类型的参数。 我有点被为什么要求我们提供一个类型变量感到困惑 我从未听说过像Array这样熟悉的东西…… 例如,让我们看一下在字符串 数组上调用的append()方法。 当我们使用自动填充来完成append函数时,系统会要求您提供一个参数: newElement:Element。 因为我们已经知道数组包含字符串,所以为什么类型不是String的参数呢? append方法将接受String并打印该方法,并将新字符串添加到Array的末尾。 那么,这是怎么回事? 为什么要求我为该方法提供一个Element,但是它将接受一个String ? 让我们再思考一下数组 。 我们创建的每个数组都有可用的append()方法,但并非所有数组都属于同一类型。 与其在String Array上使用append() ,不如在Int Array上尝试一下。 真好! 即使我们的数组类型从[String]更改为[Int],我们也可以使用Element类型来传递String或Int参数。 由于数组中各项的类型正在更改,因此使用Element可以根据数组中的内容传递正确的类型。 但仍然..什么是Element ? 这是一堂课吗? 结构? 事实证明,它被称为“通用代码”。 这里直接来自Apple文档: “通用代码使您可以编写灵活,可重用的函数和类型,这些函数和类型可以根据您定义的要求与任何类型一起使用。 您可以编写避免重复的代码,并以清晰抽象的方式表达其意图。”

集合与数组

集合是一种集合类型(一种将相关项组合在一起的方式),类似于数组,但有一些区别。 集合将不同的值存储为无序列表,而数组是可以具有重复值的有序列表。 另外,一个集合只能采用符合Hashable协议的类型,这使得该集合可以维护一组独特的值,并使其在数组上的搜索和检索速度比数组快得多。 所有基础类型都是可哈希的,并且可以与集合一起使用。 如果要使用一组自己的类或结构,则需要实现Hashable协议。 何时使用套装! 在元素的顺序不重要的情况下,或者需要确保某项仅出现一次的情况下。 让我们仔细看看! 让我们选择一个问题,并尝试使用一组解决方案,一次使用数组解决问题,然后根据执行时间和迭代次数决定哪个更快。 我们有一本词典,其中包含有关州及其州首府的信息,并且我们想知道哪个州的州首府不包含与州名相同的字符。 我们将首先使用一组回答这个问题。 我们将从在字典中进行迭代并创建两组字符开始,一组用于州名,另一组用于大写名。 然后我们将检查相交的结果-集合的基本操作之一,确定两个集合具有哪些共同的值-然后我们可以得到问题的答案。 容易吧? 代码将是: 现在,让我们尝试通过为状态名称和大写字母的名称创建一个字符数组来解决该问题,然后在大写字母数组的内部循环以检查每个字符是否存在于相应状态的数组中,或者不。 此代码将是: 如我们所见: 这两个函数都会重复前两个步骤50次,因为我们的词典有50个键。 使用一组,我们能够在一行代码中执行比较,并且该行将针对每个状态执行一次。 使用数组,我们需要一个for循环,该循环将重复50次乘以每个大写字母名称中的字符数。 因此,很明显,使用集合比使用数组来解决这些类型的问题要快。 可以通过调用每个函数100次并测量每个函数的平均执行时间来证明这一点,如下面的屏幕截图所示。 尽管在我们的示例中运行时间的差异很小,但是当与大型数据集一起使用时,这可能会产生很大的差异,因此,请始终考虑使用集作为传统数组的替代方法。

作为iOS开发人员实习生的12周-第二周

前iOS主管一直给我留下的一句话是始终追求卓越。 我本周每天醒来,在上班途中考虑这一点。 这周,我开始研究项目的一些屏幕和错误修复。 这是第二周我学到的一些东西: 一致的约束插入量/偏移量-使用一致的约束插入量和偏移量时,最好将它们包含在结构中,这样约束中就不会乱扔随机数。 例: 我得到的数据具有枚举类型,且其关联值均为“ asap”或Date类型,两者均为关联值。 我必须从数据中获取日期,但我一生都无法弄清楚。 访问没有关联值的枚举的通常方法是使用(.dotNotation)。 这对我不起作用,因为这不是您访问枚举的关联值的方式(请坚持这种想法)。 这导致我尝试了一些复杂的整理方法,将数据转换为字符串,结果是: 字符串“ date(“ 2018–07–07 11:00:00 +0000”)” 然后使用.dropFirst()和.dropLast()的字符串处理方法删除“ date()”部分,最终导致 字符串“ 2018–07–07 11:00:00 +0000” 但是由于某种原因,我尝试使用Date方法将此字符串转换为不起作用的日期….. 这是我终于向经理寻求帮助的时候。 他确认我的最初直觉是正确的, 我应该通过数据枚举的关联值来访问日期! ;-; tldr:有两种方法时: 一种简单的方法应该可以工作,但您无法弄清楚或 一个漫长而复杂的方法,这可能是您应该获得帮助的时候,因为这是浪费开发人员时间的方式。 如果我刚刚问这个问题,我可能会节省很多时间,这将花费一分钟使我走上正确的道路。 学过的知识! 无论如何,这是如何访问枚举的关联值: 通过打开枚举 通过大小写访问关联的值 3. 如何从Date()中完全拼出月份和月份的顺序日期 例如:日期(2018–07–07 11:00:00 +0000)—> 2018年7月7日 据我所知,Apple没有提供给您拼写出月份和顺序日期的方法。 所以这就是我的做法: 你这周学到了什么?