service层和model层应该全部使用静态类吗?

静态类,即整个类全部使用静态方法。好处自然是不用讲,可以不用实例化。直接使用类名::方法调用。而实例化方法,必须先实例化(new)方可调用。除此,静态方法在加载类的时候,就已经加载到内存(PS:有说其实实例方法也是编译阶段就加到内存,并无区别),并且有仅有一份,具有比实例方法更高的效率。而实例方法,必须先实例化,每个实例都是一个副本。每创建一个实例都是不小的开销。看到此处,似乎静态类拥有比实例类更实用和高效。其实这已经是我第二次在企业级项目中使用laravel框架中看全局使用静态类。

关于这个问题,我也是通过segmentfault、Google、stackoverflow等渠道找了很多观点。发现确实存在争议。有人认为不应被OOP的思想固化,怎么简单怎么来。有的则认为应该用好OOP的思想,静态类在面向对象世界中就是一个异类,不应该存在。

思考再三并结合这么多年的编程实践。我决定就此议题直接抛出自己的一些观点。希望有更深刻认识的同行能给予指导。

  • 首先,PHP是一个混合型语言,不是一个真正的面向对象的语言。可以使用OOP,也可以使用传统的过程化编程。而不像C++、java等与生俱来就是OOP语言。有统一的入口方法,必须使用严格的面向对象和规范的方式才能正确运行程序。

  • 其次,PHP生命周期是基于请求的。一次请求到响应就是完整的生命周期。不具备java等语言的内存常驻和多线程特性。FPM进程模型下,每个请求是彼此独立的进程,在内存上是隔离的。所以静态方法也不存在线程安全问题。因而尽管在PHP项目中大胆的使用静态类,在一次请求业务中, 静态方法中不出现静态属性或全局变量,即使多次调用,一般也不会出现问题。

  • 在初学OOP编程的时候总是会以人类和实例化的某个人作为例子。可以很好的区分出类和对象。但在编程实践中,以不同的角度看问题总是能提炼出不同的模型和解决方案。所以很多时候使用静态类和实例类是存在争议的。

  • 面向对象编程思维,实例化方法的提出不是为了解决性能问题。而是为了使项目更具工程化。

  • 静态方法是属于整个类的,实例方法是属于对象的。理论上如果一个方法是属于类的就不应该设计成实例方法,相反如果一个方法是属于对象的就不应该设计为静态方法。

  • 静态方法有很大的局限性。会失去继承、多态的特性,破坏封装。无法调用实例方法,使用实例属性。

  • 静态方法是面向过程的编程思维,应该避免过多使用。对于一些无状态、没有复杂多变的业务逻辑。类似助手类、工具类可以使用静态类。

  • 静态方法无法明确依赖关系,静态调用的面向过程的代码会加重类之间的耦合。需要使用实例化对象声明依赖关系。传统的new实例化方式也是一种重耦合。因而PHP几次革命从传统的include+new实例化到new实例化,使用autoload自动包含。到现代使用命名空间、 spl_autoload_register 加上 IOC容器,依赖注入等方式已经将代码解耦提升到一个新高度。也是现代流行框架(laravel、spring)所推崇的。

  • 最后,个人认为无论项目大小,项目分层如何。应当优先考虑使用实例方法,而不是静态方法。这应该是一种约定。以Laravel为例,可以使用依赖自动注入将service类实例注入控制器方法。更进一步,可以为每个service类定制一个interface契约。在服务提供者,可以将interface和实现类进行绑定。依赖注入interface,将自动解决并实例化绑定的实现类。实现controller和service的解耦以及service类的扩展可替换,体现了OOP 的接口隔离、依赖倒置、开闭原则。同时,如果深入看laravel,可以发现很多地方用到的静态方法调用,其实是使用了一种门面(Facade)设计模式进行代理。最终也是调用了实例方法,此处就不展开。

  • 当然,在工作中,你要先学会生存。我建议你应该服从一个团队的规范,尽管技术规范和主观上不合理的编程风格限制会让你感到不适。当你拥有足够的话语权和影响力的时候再去坚持自己的观点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,101评论 1 32
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,756评论 2 9
  • [Java核心技术1] 第4章 对象和类 面向对象程序设计(OOP)与面向过程的程序设计在思维方式上有很大的差别...
    椎椎隹木阅读 564评论 0 0
  • oop-klass模型 Hotspot 虚拟机在内部使用两组类来表示Java的类和对象。 oop(ordinary...
    CodeKing2017阅读 3,696评论 1 6
  • 路过一家理发店,看着店里没人,就进去理发,问一下价格,12块钱,也便宜。理发师就是老板,一个人,一个店。后来,又去...
    陈锦辉阅读 152评论 0 1