IOS 电商类app 初版架构

先上图:html

功能:ios

一、浏览商品,购买商品,支付;服务器

二、切换商店、查看订单、订单投诉、意见反馈;网络

三、登录、收货地址管理;session

四、app首次启动的初始化界面;闭包

 

架构上:架构

 

 

箭头的指关系 表明着 直接调用,也表明着持有引用的意思。app

全部的实例均可以经过监听event,达到交流的效果。框架

其中Model是单例,Controller 是storyBoard 上实例,view是Controller运行时加载并初始化;异步

Message是工厂模式,每个协议都实例化一个对象来解决;

Event经过封装NSNotifycation实现。

网络通信是经过Message调用AFNetworking。

 

 

设计中遇到的问题:

1,网络层请求的封装。一开始的作法是定义一个server类来处理请求,头文件中定义请求的类型,全部的网络请求都走server类,server类直接调用AFNetworking.

大体的形式以下:

Server:NSObject

{

    -(void) requestLogin;

    -(void) requestLogout;

  ....

}

这样的好处是直接调用,开发方便,逻辑也比较简单。

坏处是,全部的代码都写在一块儿,不方便维护,同时很差作统一的逻辑处理(好比说session过时等)。

 

如今采用的作法:

定义一个BaseMessage,封装AFNetworking的调用,还有统一的逻辑处理。

同时定义OrderMessage,CartMessage,GoodsMessage,ShopMessage等继承BaseMessage,来具体实现特定的逻辑。

这样作的好处,把逻辑分类,代码按照模块分散到每一个SubMessage,方便维护。

 

还能够优化的地方:

如今的请求是一个Message就是一个网络请求(http),处理完以后要在Message抛出事件,来通知其余模块的信息。而且,每一个Message都是相互独立的,并无统一调度的过程。

能够新建一个MessageQueue类,来存放全部的Message请求,经过MessageQueue来调度http请求。

这样的涉及到的问题是:结果回来后,如何通知其余对象?

作法1:

当请求Message的时候,self实现一个接口,而且传入self;回调的时候,直接经过接口调用;

作法2:

请求的时候,带一个闭包参数,回调的时候直接调用闭包;

作法3:

请求以后监听事件;回调时经过事件响应;

 
比较理想的作法:
有controller 、 message 、msgCenter三个实例。
controller监听事件,发送message;
message实现接口,本身把本身添加进msgCenter队列;
msgcenter对BaseMessage进行处理,经过接口来查询message 里ID等详细信息;回调后,经过调用message的接口。
 
 controller 和 message 用的是监听者模式;
msgCenter 和 message 之间用的是代理模式;
msgCenter 能够实现异步的与服务器交互,和对message 的统一处理。
 (  http://www.cnblogs.com/loying/p/4804566.html  参考自 蘑菇街的IM 网络层)
 
 
 
2,MVC框架的实现。ios的设计,自己就含有不少MVC的思想,好比说要实现一个自定义UITableView,就要继承UITableView,自定义delegate,与Controller的交流 是经过delegate实现。同时,一个页面就是一个controller,也要继承UIViewController。
天然而然地,在写代码的时候就会M(model)、V(View)、C(controller)的区分。
但在实际的需求中,遇到一些正常的需求的时候,若是没有设计好,也会很棘手。
好比说:首页下方的购物车模块、商品展现的模块,这些都是须要重复出现的模块,也就是须要重用的模块。如何设计购物车模块,使得购物车模块 和 持有购物车的模块(首页、子类目等)之间没有耦合,也是一个麻烦的事情。
具体的需求有几个:
一、购物车点开的时候,页面除购物车的背景要灰掉,同时购车要有上滑的动画;
二、点击购物车或者点击背景的时候,购物车弹下,同时灰色背景去除;
三、购物车中点击商品的增减,要实时反馈到页面上(首页、子类目等);
四、购物车点开以后的大小,由购物车内的物品决定,有最大高度;
五、购物车的物品减到0的时候,不消除;
....
 
controller与view之间的交互,controller持有view,能够 直接调用view;view要调用controller或者其余view,能够经过事件、委托等方式;
不论是事件仍是委托,为的是解耦,让view与controller之间不耦合,因此切记不可在view定义一个controller的属性,而后传递controller进来。
解决方案:
view 与 controller 之间用委托(记得@property(weak),不然循环引用,内存没法释放);
view 与 view 之间用事件机制;
 
在interface builder能够用outlet 来作委托机制,很是方便,具体的流程和UITableView相似;
 
 
3,事件机制
没有用第三方的事件机制(如EventBus等),用的是NSNotifycation来实现;
一开始的作法是:
#define NOTIFY_SERVER_USER_LOGIN     @"NOTIFY_SERVER_USER_LOGIN"
#define NOTIFY_UI_REQUEST_PHONE_CALL  @"NOTIFY_UI_REQUEST_PHONE_CALL"
直接define具体的协议,若是带有数据,就存到notify的userInfo;
这样在代码写了比较多时候,当改动一个notify的userInfo的时候,常常会忘记改其余的某处,并且每每记不得userInfo里面的数据格式,不便于维护;
 
因而在NSNotify的基础上作了一层封装:
定义一个BaseEvent,负责把event的类型转成nsnotify(类型名字@"",属性转成dict),同时把nsnotify转成event;
同时Event分红几类ErrorEvent ServerEvent UIEvent DataEvent等。

 好比:

@interface UIMessageConfirmEvent : BaseEvent

 @property (nonatomic , copy) NSString* message;

@end

发送事件的时候,能够直接在event类型里面给message赋值;

 

 

 开发中的几个原则:

1,不要有很大的文件,除非不多改动;(大文件,不方便维护和开发)

2,一个函数尽可能只作一个功能,若是有多个地方调用,要保证调用的意义是相同的;(尽可能不要在调用参数中带默认参数,或者在复杂调用中带flag来标示此次调用的含义)

3,调用时的参数检查,通常由被调用的函数检查参数;若是涉及到参数不对时,须要有相应的逻辑操做,好比弹出提示框等的,尽可能由调用者来检查参数;

相关文章
相关标签/搜索