当前位置: 澳门新濠3559 > 操作系统 > 正文

注册中心里并没有信息,而却自行实例化并像整

时间:2019-12-21 19:57来源:操作系统
我要搞一个框架,需要根据不同的业务标识创建不同的模型对象,比如bizSpec是case的时候创建CaseRowData对象,bizSpec是casetype的时候创建CaseTypeRowData对象,我是期望我提供一个抽象类,然后

我要搞一个框架,需要根据不同的业务标识创建不同的模型对象,比如bizSpec是case的时候创建CaseRowData对象,bizSpec是casetype的时候创建CaseTypeRowData对象,我是期望我提供一个抽象类,然后别人的**RowData扩展我这个类,实现一个getRegisterationKey接口,自动注册"key-类型"到我的框架内部的RowDataCreatorDelegate的一个ConcurrentHashMap里,然后框架的其他地方使用delegate传入key直接取到模型class然后通过反射实例化,但是有个问题是如果我把注册的逻辑放到构造函数里做,在调delegate的创建实例前其实是没有RowData实例的,注册中心里并没有信息;如果放到static代码块里,也不行,因为在这种模式下用户自己扩展的类在调delegate.create前并没有加载,注册中心里还是没有信息。各位大佬有没有什么办法呢???

delegate

优点:

  • 语法严格, 所有监听的事件必须是在 delegate 协议中有清晰的定义
  • 如果 delegate 中的一个方法没有实现那么就会出现编译警告/错误
  • 协议必须在 controller 的作用域范围内定义
  • 在一个应用中的控制流程是可跟踪的并且可识别的
  • 在一个控制器中可以定义多个不同的协议, 每个协议有不同的 delegates
  • 没有第三方对象要求保持/监视通讯过程
  • 能够接收调用的协议方法的返回值. 这意味着 delegate 能够提供反馈信息给controller
  • 注册中心里并没有信息,而却自行实例化并像整个系统提供这个实例.。经常被用在存在父子关系的对象之间的通信, 例如控制器和控制器的 View

缺点

  • 需要定义很多代码: 1.协议定义:2.Controller的delegate属性:3.在delegate本身中实现delegate方法定义
  • 在释放代理对象时, 需要小心的将delegate改为nil. 一旦设定失败,那么调用释放对象的方法将会出现内存 crash
  • 在一个 Controller 中有多个 delegate 对象, 并且 delegate hi是遵守同一个协议, 但还是很难告诉多个对象同一件事件.
  • 经常用在一对一的通信.

单例模式

Notification

优点

  • 代码量小, 实现简单
  • 对于一个发出的通知, 多个对象能做出反应, 即一对多的实现方式.
  • Controller 能传递 Context 对象, Context 对象存储关于发送通知的信息.

缺点

  • 编译器不会检查通知是否能够被观察证正确的处理
  • 在释放注册的对象时, 需要在通知中心取消注册
  • 在调试的时候应用的工作以及控制过程很难跟踪
  • 需要第三方对象来管理Controller与观察者对象之间的联系
  • controller 和观察者需要提前知道通知名称, UserInfo dictionary key. 如果这些没有工作区间定义, 那么会出现不同步的情况:
  • 通知发出后, Controller 不能从观察者活得任何的反馈信息

单例模式作为一种目标明确、结构简单、理解容易的设计模式,在软件开发中使用频率相当高,在很多应用软件和框架中都得以广泛应用。

KVO

优点

  • 能够提供一种简单的方法实现两个对象间的同步.
  • 能够对非我们创建的对象, 即内部对象的状态改变做出响应, 而且不需要改变内部对象(SDK对象)的实现
  • 能够提供观察的属性的最新值以及先前值
  • 用 key path 来观察属性, 因此也可以观察嵌套对象
  • 完成了对观察对象的抽象, 因为不需要额外的代码来允许观察值能够被观察
  • 可以一对多

缺点

  • 我们观察的属性必须使用 string 来定义, 因此在编译的时候不会出现警告和检查
  • 对属性重构会导致我们的观察代码不可用
  • 复杂的"IF"语句要求对象正在观察多个值. 这是因为所有的代码通过一个方法来指向.
  • 当释放观察者时不需要移除观察者

1).主要优点

从设计模式的角度去分析 Delegate, Notification, KVO 的区别

  • 效率方面 delegate 比 NSNotification高. delegate 方法比 notification 更加直接, 最典型的特征是, delegate 方法往往需要关注返回值, 也就是 delegate方法的结果.比如 windowShouldClose, 需要关系返回的是 YES 还是 NO. 所以deleagete方法往往包含 should 这个很传神的词. 也就是好比你做我的delegate, 我会问你我想关闭窗口你还愿意吗? 你需要给我一个答案, 我根据你的答案来决定如何做下一步.相反的, notification 最大的特色就是不关心接受者的态度. 我直管把通告放出来, 你接受不接受就是你的事情, 同时我也不关心结果. 所以 notification 玩玩用 did 这个词汇, 比如 NSWindowDidResizeNotification, 那么 NSWindow 对象放出这个 Notification 后就什么都不管了, 也不会等待接受者的反应.
  • KVO 和 NSNotification 和 delegate 一样, KVO 和 NSNotification 的作用也是类和类之间的通信, 和 delegate 不同的是
    • KVO 和 NSNotification 都是负责发出通知, 剩下的事情就不管了, 所以没有返回值
    • delegate 只是一对一, 而这俩个可以一对多.

总结

单例模式的主要优点如下:

什么是设计模式

  • 设计模式是为特定场景下的问题而制定的解决方案. 特定场景指问题所在的重复出现的场景, 问题指特定环境下你先达成的目标. 同样的问题在不同的环境下会有不同的限制和挑战. 定制的解决方案是指在特定环境下克服问题的限制条件而达成目标的一种设计

(1)单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。

设计模式的分类

  • 设计模式分为三种类型, 共 23 种
    • 创建型模式: 单利模式, 抽象工厂模式, 建造者模式, 工厂模式, 原型模式.
    • 结构型模式: 适配器模式, 桥接模式, 装饰模式, 组合模式, 外观模式, 享元模式, 代理模式.
    • 行为型模式: 模板方法模式, 命令模式, 迭代器模式, 观察着模式, 中介者模式, 备忘录模式, 解释器模式(interpreter模式), 状态模式, 策略模式, 职责联模式(责任链模式), 访问者模式.

(2)由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。

类工厂方法

  • 类工厂方法的实现是为了向客户提供方便, 他们将分配和初始化合在一个步骤中, 返回被创建的对象, 并进行自动释放处理.
  • 这些方法的形式是 + (type)className... (其中 className 不包括任何前缀)
  • 工厂方法可能不仅仅为了方便使用. 他们不但可以将分配和初始化合在一起, 还可以为初始化过程提供对象的分配信息.
  • 类工厂方法的另一个目的是使类(比如 NSWorkspace) 提供单利. 虽然 init... 方法可以确认一个类在每次程序运行过程中只存在一个实例, 但它需要首先分配一个"生的"实例, 然后还必须释放该实例. 工厂方法可以避免为可能没有用的对象盲目分配内存.

(3)允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例单例对象共享过多有损性能的问题。

单例

单例模式的意思就是只有一个实例. 单例模式确保摸一个类只有一个实例, 而却自行实例化并像整个系统提供这个实例.
要点

  • 澳门新濠3559,一个类只能有一个实例
  • 必须是自行创建的实例
  • 必须自行向整个系统提供这个实例
    优点
    -实例控制: singleton 会组阻止其他对象是实例化自己的 singleton 对象的副本, 从而确保所有对象都访问唯一实例.
  • 灵活性: 因为类控制了实例化过程, 所以类可以更加灵活修改实例化过程.

2).主要缺点

手写单例

static Class *class;
+ (Class *)shareInstance {
    if(!class) {
        static dispatch once_t Token;
        dispatch_once (&token, ^ {
        class = [[class alloc] init];
      };
    }
return class;
}

单例模式的主要缺点如下:

简述观察者模式,

  • 观察者模式 (Observer) 是一个或多个对象对另一个对象进行观察, 当被观察对象发生变化时, 观察者可以直接或间接的得到通知, 从而能自动的更新观察者的数据, 或者进行一些操作.
  • 具体到 iOS 的开发中, 实现观察者模式常用的方式有 KVO 和 Notification 俩种.
  • 俩者的不同在于, KVO是被观察者主动向观察者发送消息: Notification 是被观察者向 NotificationCenter 发送消息, 再由 NotificationCenter post 通知到每个注册的观察者.

(1)由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。

MVC,单例, 代理

  • MVC: 就是 Model-View-Controller 的缩写, M 指的是业务逻辑, V 指的是用户界面, C 指的是控制器. MVC是架构模式, 是讲 M 和 V 的代码分离, 从而使同一个程序有不同的表现形式.
  • 单例模式: 一个类只有一个实例
  • 代理模式: 代理模式给某一个对象提供一个代理对象, 并由代理对象控制对源对象的引用, 比如一个工厂生产了产品, 并不想直接卖给用户, 二十高了很多代理商, 用户可以直接找代理商买东西, 代理商从工厂进货, 常见的如QQ的自动回复就属于代理拦截, 代理模式在 iphone 中得到广泛应用.

(2)单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。

测试, MVC 优点不正确的是

A. 低耦合性
B. 高重用性和可适用性
C. 较低的声明周期成本
D. 代码高效率

  • 参考答案: D
  • 理由: MVC 只是一个钟设计模式, 他的出现有比较久的历史了. Model-Controller-View 是在开发中最常见到的设计模式, 通过将 Model, View, Controller 三者相互联系, 以 Model 作为数据加工厂, 以 Controller 作为桥梁, 处理业务, 而 View 只是数据展示层, 理应与业务无关. MVC 设计模式降低了耦合性, 提供了重用性和适用性, 可以有效的提高开发效率.

(3)现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。

MVVM

  • MVVM 框架相对于传统的 MVC 来说, 主要区别在于把原本在 C 中 (ViewController) 的业务逻辑, 网络请求, 数据储存等操作和表现逻辑, 分离到 ViewModel 中, 从而是 ViewController 得到精简
  • MVC 中, Controller 同时操作 Model 和 View; MVVM 中, ViewModel 作为一个过渡, Model 的数据获取和加工由 ViewModel 负责, 得到适合 View 的数据, 利用绑定机制, 使得 View 得以自动更新.
    优点:
    • 层次更加分明清晰
    • 代码简洁优雅
    • 减少 VC 的复杂性
    • 代码和界面完全分离
    • 方便测试
      缺点:
    • MVVM 需要使用数据绑定机制, 对于 os x 开发, 可以直接使用 cocoa Binding, 对于 iOS , 没有太好的数据绑定方法, 可以使用 KVO, 但是如果需要绑定的属性太多的话, 需要编写大量的 Selector 代码.
    • reactiveCocoa 提供了一种很方便优雅的绑定机制.

3).适用场景

ReactiveCocoa

  • RAC 具有函数式编程和响应式鞭策的特性
  • 视图解决以下问题
    • 传统 iOS 开发过程中, 状态以及状态之间依赖过多的问题
    • 传统 MVC 架构的问题: Controller 比较复杂, 可测试性差
    • 提供统一的消息传递机制

在以下情况下可以考虑使用单例模式:

ViewController瘦身

  • 把 Data Source 和其他 Protocols 分离出来 (将 UITableView 或者 UICollectionView 的代码提取出来放在其他类中)
  • 将业务逻辑移到 Model 中 (和模型有关的逻辑全部在 Model 中写)
  • 把网络请求逻辑转移到 Model 层 (网络请求依靠模型)
  • 把 View 代码移到 View 层 (自定义View)

(1)系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。

项目里使用的设计模式

  • 单利设计模式: UIApplication, NSUserDefaults, 是苹果封装的单利. 在项目中经常会将用户数据管理封装成一个单利类, 因此用户的信息需要全局使用.
  • MVC 设计模式: 现在却大部分项目都是基于 MVC 设计模式的, 现在有一部分开发者采用 MVVM, MVP 等模式.(MVP 中的 P 即为 Presenter:作为model和view的中间人,从model层获取数据之后传给view,使得View和model没有耦合。)
  • 通知(NSNotification)模式: 通知在开发是必不可少的, 对于跨模块的类交互, 需要使用通知, 对于多对多的关系, 使用通知更好的实现. (页面跳转, 夜间模式什么的)
  • 工厂设计模式: 其中生成控件的 API, 都已经封装成一套, 全部是扩展的类方法, 可以简化很多代码
  • KVC / KVO 设计模式: 有时候需要监听某个类属性值的变化而做出响应的变化, 当变化时, 需要更新UI显示, 这个时候使用 KVC / KVO 设计模式就很方便了

(2)客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

如何实现单例

  • 用 GCD dispatch_one 来创建, 保证单例只会创建一次. 如果不小心销毁了, 在调用方法不会创建.
    注意: 实际开发中不会去重写内存管理方法, 单例一旦创建, 整个 App 使用的过程都不会释放, 占用内存, 所以可以滥用.

委托模式(代理模式)

1).主要优点

(1).非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义。

(2).如果delegate中的一个方法没有实现那么就会出现编译警告/错误

(3).协议必须在controller的作用域范围内定义

(4).在一个应用中的控制流程是可跟踪的并且是可识别的;

(5).在一个控制器中可以定义定义多个不同的协议,每个协议有不同的delegates

(6).没有第三方对象要求保持/监视通信过程。

(7).能够接收调用的协议方法的返回值。这意味着delegate能够提供反馈信息给controller

2).主要缺点

(1).需要定义很多代码:1.协议定义;2.controller的delegate属性;3.在delegate本身中实现delegate方法定义

(2).在释放代理对象时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash

(3).在一个controller中有多个delegate对象,并且delegate是遵守同一个协议,但还是很难告诉多个对象同一个事件,不过有可能。

观察者模式

观察者模式在iOS中有两个用法,NSNotification和KVO

NSNotification 涉及到两个对象,观察者和被观察者,观察者注册监听,当被观察者执行某个操作时,会发送一个通知,注册该通知的观察者就会收到这个通知,然后去执行下一步操作,通知是广播模式,支持一对多。

优势:

(1).不需要编写多少代码,实现比较简单;

(2).对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单

(3).controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息

缺点:

(1).在编译期不会检查通知是否能够被观察者正确的处理;

(2).在释放注册的对象时,需要在通知中心取消注册;

(3).在调试的时候应用的工作以及控制过程难跟踪;

(4).需要第三方对喜爱那个来管理controller与观察者对象之间的联系;

(5).controller和观察者需要提前知道通知名称,如果这些没有在工作区间定义,那么会出现不同步的情况;

(6).通知发出后,controller不能从观察者获得任何的反馈信息。

KVO是一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。前面两种模式更加适合一个controller与任何其他的对象进行通信,而KVO更加适合任何类型的对象侦听另外一个任意对象的改变(这里也可以是controller,但一般不是controller)。这是一个对象与另外一个对象保持同步的一种方法,即当另外一种对象的状态发生改变时,观察对象马上作出反应。它只能用来对属性作出反应,而不会用来对方法或者动作作出反应

优点:

(1).能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;

(2).能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;

(3).能够提供观察的属性的最新值以及先前值;

(4).用key paths来观察属性,因此也可以观察嵌套对象;

(5).完成了对观察对象的抽象,因为不需要额外的代码来允许观察值能够被观察

缺点:

(1).我们观察的属性必须使用strings来定义。因此在编译器不会出现警告以及检查;

(2).对属性重构将导致我们的观察代码不再可用;

(3).复杂的“IF”语句要求对象正在观察多个值 。这是因为所有的观察代码通过一个方法来指向;

(4).当释放观察者时不需要移除观察者。

说说delegate跟NSNotification、KVO有什么区别和联系吧

三者都是为了代码解耦,delegate只支持一对一,而另外两个支持一对多;delegate有很明确的控制链,代码逻辑结构更加清晰易懂,而另外两个这方面就偏弱了;delegate跟NSNotification主要针对Controller之间的通信场景,而KVO主要针对Controller与属性之间的通信场景。

工厂模式

在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。

工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。工厂方法也叫做虚构造器(Virtual Constructor).

应用场景:工厂方式创建类的实例,多与代理模式配合,创建可替换代理类。

1).优点:

(1).易于替换,面向抽象编程,只与抽象工厂和易变类的共性抽象类发生调用关系

(2).代码结构更加清晰,代码也更简洁

敏捷原则:DIP依赖倒置原则

2).缺点:

(1).增加了代码的复杂度

(2).增加了调用层次

(3).增加了内存负担

实例:项目部署环境中依赖多个不同类型的数据库时,需要使用工厂配合代理完成易用性替换

策略模式

应用场景:定义算法族,封装起来,使他们之间可以相互替换。

优势:使算法的变化独立于使用算法的用户

敏捷原则:接口隔离原则;多用组合,少用继承;针对接口编程,而非实现。

实例:排序算法,NSArray的sortedArrayUsingSelector;经典的鸭子会叫,会飞案例。

注意事项:1,剥离类中易于变化的行为,通过组合的方式嵌入抽象基类

2,变化的行为抽象基类为,所有可变变化的父类

3,用户类的最终实例,通过注入行为实例的方式,设定易变行为

防止了继承行为方式,导致无关行为污染子类。完成了策略封装和可替换性。

原文链接:

编辑:操作系统 本文来源:注册中心里并没有信息,而却自行实例化并像整

关键词: