第3回 接口和API设计 52长达笔记

第3章
接口与API设计 52条笔记

  由于公司的工作部署,一向于研其他技术,所以直接未曾时间更新博客,先天总算可以告一段落手边的工作,写有新内容了。

第15长长的:
用前缀制止命名空间龃龉

  应用场景:集团门户网站会依照情节各异,设置不同的板块,如初浪有体育,娱乐频道,等等。有的情形下用吃不同之板块设置不同之二级域名,如初浪体育sports.sina.com.cn。

Objective-C
没有其余语言这种内置的命名空间机制
。鉴于此,大家于起名时如千方百计避免地下的命名争执,否则很爱就重名了。假使发命名争辨naming clash ,那么应用程序的接连过程就胡出错。

  以asp.net core
mvc中,假如假定促成板块的机能,可能会晤受不同之板块建立不同的控制器(当然为发外的技巧,这里不钻探实现情势的好坏),在这种状态下,如何给控制器绑定上独有的二级域名,比如体育频道对应的控制器叫SportController,通过sports.XXX.com域名访问系统的时节,直接进去SportController,并且通过此二级域名无法访问其他的控制器。

图片 1

  上边说罢场景了,下边来拘禁下何以贯彻。

防止这一个问题之唯一做法即是变相实现命名空间:为拥有名称都丰硕适量的前缀。

  以asp.net core
mvc中起路由于规则配置,配置的地方以Startup.Configure方法被,具体代码如下:

 

  

第16长:
提供全能先河化方法

app.UseMvc(routes =>
{
      routes.MapRoute(
           name: "default",
           template: "{controller=Home}/{action=Index}/{id?}",
           defaults: new { area="admin"});
});

把这种可为目的提供必需信息以便其可以不辱使命工作的起先化方法就是做
指定先河化方法 designated initialzier.

  遗憾的凡勿协理对域名之支撑(我当下打探的凡,假诺生题目,欢迎我们指正)。通过routes.MapRouter注册路由规则,并进入到RouteCollection中,当有请求过来后,RouterCollection循环所有注册好的IRouter对象,找到第一独十分的IRouter停止。虽然框架不匡助域名配置规则,然则我们得以友善失去贯彻一个IRouter,在中间实现二级域名判断的逻辑,我此少起名为SubDomainRouter,具体实现代码如下:

倘诺成立实例的不二法门不止一栽,那么是近乎即会生出差不三只伊始化方法。不过假诺当中间选定一个作为designated
initializer ,令其他伊始化方法都来调整用它们。

  public class SubDomainRouter : RouteBase
    {
        private readonly IRouter _target;
        private readonly string _subDomain;
        public SubDomainRouter(
           IRouter target,
           string subDomain,//当前路由规则绑定的二级域名
           string routeTemplate,
           RouteValueDictionary defaults,
           RouteValueDictionary constrains,
           IInlineConstraintResolver inlineConstraintResolver)
           : base(routeTemplate,
                  subDomain,
                  inlineConstraintResolver,
                  defaults,
                  constrains,
                  new RouteValueDictionary(null))
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (subDomain == null)
            {
                throw new ArgumentNullException(nameof(subDomain));
            }
            _subDomain = subDomain;
            _target = target;
        }
        public override Task RouteAsync(RouteContext context)
        {
            string domain = context.HttpContext.Request.Host.Host;//获取当前请求域名,然后跟_subDomain比较,如果不想等,直接忽略

            if (string.IsNullOrEmpty(domain) || string.Compare(_subDomain, domain) != 0)
            {
                return Task.CompletedTask;
            }
        
       //如果域名匹配,再去验证访问路径是否匹配

            return base.RouteAsync(context);

        }

        protected override Task OnRouteMatched(RouteContext context)
        {
            context.RouteData.Routers.Add(_target);
            return _target.RouteAsync(context);
        }

        protected override VirtualPathData OnVirtualPathGenerated(VirtualPathContext context)
        {
            return _target.GetVirtualPath(context);
        }
    }

图片 2

  从者的代码我们才见到了域名检测,但是什么把域名定向到一定的控制器上,这尽管待我们当登记之IRouter的时光做来作品,直接上代码:

方几乎独开头化方法被,initWith提姆(Tim)eIntervalSinceReferenceDate:是
designated initializer.

public static class RouteBuilderExtensions
    {
        public static IRouteBuilder MapDomainRoute(
            this IRouteBuilder routeBuilder,string domain,string area,string controller)
        {
            if(string.IsNullOrEmpty(area)||string.IsNullOrEmpty(controller))
            {
                throw new ArgumentNullException("area or controller can not be null");
            }
            var inlineConstraintResolver = routeBuilder
                .ServiceProvider
                .GetRequiredService<IInlineConstraintResolver>();

                string template = "";

                    RouteValueDictionary defaults = new RouteValueDictionary();
                    RouteValueDictionary constrains = new RouteValueDictionary();
                    constrains.Add("area", area);
                    defaults.Add("area", area);
                    constrains.Add("controller", controller);
                    defaults.Add("controller", string.IsNullOrEmpty(controller) ? "home" : controller);
                    defaults.Add("action", "index");

                    template += "{action}/{id?}";//路径规则中不再包含控制器信息,但是上面通过constrains限定了查找时所要求的控制器名称
                    routeBuilder.Routes.Add(new SubDomainRouter(routeBuilder.DefaultHandler, domain, template, defaults, constrains, inlineConstraintResolver));


            return routeBuilder;
        }
}

 

  最终我们即使足以于Startup中注册对应之平整,如下:

第23长:通过信托以及数据源协议举行对象中通信

app.UseMvc(
      routes =>
        {
            routes.MapDomainRoute("xxx.domain.com","areaname","controllername");

            routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}",
                  defaults: new { area = "web" });
        });

拖欠格局的宏旨是

定义一拟接口,某目标要想接受外一个目的的嘱托,则用按照从此接口,以便成为那么些委托对象
delegate.而及时其它一个目的则足以被这委托对象回传一些音,也足以当闹相关事件不时通报委托对象。

  实现格局恐怕无是极其好之,不过已经满足了主旨要求,即使我们发出再好之章程,欢迎研究交换。

 

  

相似通过协商
这项语言特色来是实现这么些格局,整个Cocoa系统框架依旧如此做的。

  

第24长长的:
将类的兑现代码分散到便于管理的频繁独分类中

  

恍如吃时容易填满各样措施,而这多少个情势的代码则遍堆放在一个宏伟的落实公文中。

经Objective-C的归类编制,把看似代码按逻辑划入多少个分区中,这对出及调节都爆发益处。

 

将个人信息建模为类。

图片 3

可就此分类机制将方底类改写成下面这样:

图片 4

近年来,类的落实代码依据措施分成了少数单部分。所以说,这项语言特色当然就叫分类
啦 。

行使分类编制后,依然可以管全类都定义在一个接口文件中,并将这多少个代码写以一个兑现公文中。不过趁分类数量多,当前即时卖实现文件很快便会暴涨。此时,可以把每个分类提取到个其它文书中失。

以EOCPerson为条例,可以按其分类分成以下八只公文:

图片 5

图片 6

图片 7

透过分类机制,可以将看似代码分成多易管理的稍片,以便单独检视
。使用分类编制后,假如想用分类中之不二法门,那么一旦记得在引入EOCPerson.h时一样并引入分类的条文件。

即便稍有接触麻烦,不过分类如故是同一栽管理代码的好办法。

第25长长的:总是为老三正值的归类名加前缀。

第26漫长:
勿在分拣中宣称属性

特性是封装数据的不二法门。就算从技术上说,分类也可表明属性,但这种做法应该尽量避免。

关系对象可以缓解在分拣中无可以合成实例变量的题目。

图片 8

那般做行,但无绝帅。要管一般的代码写过多举,而且每当内存管理问题达到容易出错,因为我们于呢性实现存取方法时,日常会忘记听从其内存管理语义。

尽管这一个办法无特别,但笔者非引进。

拿性能定义在主接口中设比定义在分拣里洗得差不多。

关于分类机制,则答应以那一个精晓啊同种手段,目标在增加类的坚守。

奇迹只是念属性依然好以分拣中动用的。

出于拿到情势并无聘数,而且性能为不需要由实例变量来兑现,所以可以像下这样来贯彻分类:

图片 9

第27条:
使用class-continuation 分类 隐藏实现细节

第28长达:通过协议提供匿名对象

商定义了千篇一律密密麻麻措施,遵循此研讨的靶子应实现他们。于是,我们得用协议将好所写的API只受之兑现细节隐藏起来,将回到的对象设计为仍从此协议的纯id
类型。

以概念为委托者
delegate这么些特性时,可以这么勾画

@property
(nonatomic ,weak )id <EOCDelegate>delegate;

由该属性的类是id<EOCDelegate>,所以实际上任何类似的对象还是可以担任这同样性质,即使该类不连续自NSObject也足以,唯有遵循EOCDelegat协议就执行。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图