编程

算法中的大O表示法

算法中的大O表示法

1.算法概念

计算机科学中的算法指的就是计算机执行的指令。

算法是计算机处理信息的本质,因为计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务,如计算职工的薪水或打印学生的成绩单。

一般地,当算法在处理信息时,会从输入设备或数据的存储地址读取数据,把结果写入输出设备或某个存储地址供以后再调用。

               -----------       
      输入 --> |   算法    | --> 输出
               -----------  

算法的核心是创建问题抽象的模型和明确求解目标,之后可以根据具体的问题选择不同的模式和方法完成算法的设计。

2. 时间复杂度

算法的时间复杂度是指算法需要消耗的时间资源。

一般来说,计算机算法是问题规模n 的函数f(n),算法的时间复杂度也因此记做:

T(n) = O(f(n))

算法执行时间的增长率与f(n) 的增长率正相关,称作渐近时间复杂度(Asymptotic Time Complexity),简称时间复杂度。

3. 空间复杂度

算法的空间复杂度是指算法需要消耗的空间资源。

其计算和表示方法与时间复杂度类似,一般都用复杂度的渐近性来表示。

同时间复杂度相比,空间复杂度的分析要简单得多。

4. 大 O 表示法

像 GitHub 一样渲染 Markdown

个人一直比较喜欢 GitHubMarkdown 渲染风格,支持的语法和语法高亮更多而且代码看起来十分舒服。但是有时候想写点东西在自己的网站上展示出来,之前使用的方案是用 sublimetext-markdown-preview 这个插件生成 HTML ,生成的时候选择 GitHub ,然后把 HTML 文件传到主机上显示。然而现在换用 atom 了, 它自带的渲染并不是很好看。一堆 HTML 维护起来也不太方便,于是就有了这个。首先我使用的是 Nginx + php-fpm ,Apache 应该也可以搞定。

GitHub 有渲染 Markdown 的 API ,官方文档在 这里 ,既然有那就直接拿来用好了,反正 VPS 在美国请求 GitHub 不成问题。但是这个 API 只渲染出一个 HTML 框架,还需要

面向接口编程

基本信息

在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。
1.关于接口的理解。
接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。
接口的本身反映了系统设计人员对系统的抽象理解。
接口应有两类:第一类是对一个体的抽象,它可对应为一个抽象体(abstract class);
第二类是对一个体某一方面的抽象,即形成一个抽象面(interface);
一个体有可能有多个抽象面。
抽象体与抽象面是有区别的。

面向对象设计原则

4.2 面向对象设计7大原则
设计实现一个系统时,我们一般先按功能划分好模块,以模块中核心类为起点,根据功能逐步向周边延展设计其它类。
设计模式在这个过程中可以帮助我们进行高质量的代码设计。但是模式是有限的,这些优秀的设计模式背后有没有什么通用的指导原则呢?
依赖倒置原则:面向接口编程,不要针对实现编程。实现意味着应对变化的能力下降,尽量延迟到调用时再具体化。

开闭原则:对扩展开放,对修改关闭。比较好理解,扩展新增引入的风险相对修改更可控一些。修改往往意味着,系统扩展性不够。

里氏替换原则:继承父类的目的是为了复用。高质量的继承关系,是衍生类可以完全替换掉基类,并且系统的行为不受到影响。如果子类不能完全替换父类,说明继承是不彻底的,复用的目的就没有达到。

单一职责原则:一个类应该只承担一个职责。承担的职责过多,职责之间可能会相互耦合。这里最难的就是划分职责,职责必须恰如其分地表现实体的行为。比如用户账号可以修改基础信息,会员可以持有会员卡。如果不加以区分,只抽象一个用户实体包括所有的行为,显然是不合适的。

接口隔离原则:适度细化接口,接口的行为尽量少。分治的思想,降低复杂性,系统更可控。

迪米特法则:一个类对依赖的类知道的越少越好。本质目的是将复杂度控制在一定范围内。

组合/聚合复用原则:复用即可以通过继承实现,也可以通过组合 / 聚合实现。区别在于,继承表达 is-a的逻辑关联,目的在描述结构,而不是复用。

------
面向对象设计七大原则:“开闭原则”是总纲,告诉我们要“对扩展开放,对修改封闭”;“里氏替换原则”告诉我们“不要破坏继承体系”;“依赖倒置原则”告诉我们要“面向接口编程”;“单一职责原则”告诉我们实现类要“职责单一”;“接口隔离原则”告诉我们在设计接口时要“精简单一”;“迪米特法则”告诉我们要“降低耦合度”;“合成复用原则”告诉我们要“优先使用组合或者聚合关系复用,少用继承关系复用”
---------

开闭原则:对拓展开放,对修改关闭。
里氏替换原则:不该破坏类的继承体系,不应该复写父类的方法,子类可以拓展父类功能,但不能改变父类原有的功能。
依赖倒置原则:面向接口编程,而不是面向实现编程。
单一职责原则:尽量保持实现类的职责单一。
接口隔离原则:设计接口的时候要精简单一。
迪米特法则:降低耦合度,只和你的朋友交流。
合成复用原则:优先使用组合聚合关系,代替继承关系。

开闭原则实现途径:
里氏替换原则
依赖倒置原则

高内聚低耦合:
单一职责原则
接口隔离原则
迪米特法则
合成复用原则


面向对象编程时有以下几个选择:
1,多用组合,少用继承
2,针对接口编程,不针对实现编程
3,为交互对象之间的松耦合设计而努力
4,类应该对扩展开放,对修改关闭
5,依赖抽象,不要依赖具体类 ​


设计模式-六大原则、模式类型、规则

无用的设计模式-上篇

作者:吕浩

部门:有赞美业

提到设计模式,有一个非常有意思的现象:
理论学习中,几乎所有的开发人员都认为它非常有用很重要。
工作实践中,绝大部分开发人员在项目中找不到合适的应用场景。
设计模式学了一遍又一遍,却毫无用武之地。大概设计模式最好的归宿,就是存在程序员的深深的脑海里。

【设计模式】设计原则-SOLID、DRY、KISS、YAGNI、LOD

修改记录 修改时间 备注
新建 2021.02.09 整理自极客时间-王争的设计模式之美(推荐购买学习)

1. SOLID原则

1.1 SRP(Single Responsibility Principle) 单一职责

1.1.1 定义:一个类或模块只负责完成一个功能。

理解:不要设计大而全的类,要设计粒度小、高性能单一的类。该原则的目的是为了实现代码高内聚、低耦合、提高代码复用性、可读性以及可维护性。

1.1.2 以下场景可能会出现类没有指责单一:

  • 类中的代码行数、函数、属性是否过多。可以考虑对该类进行拆分;
  • 类依赖的其他类过多,或者依赖类的其他类过多,不符合高内聚、低耦合的设计思想;
  • 私有方法过多,可以考虑将私有方法独立到新类中,设置为 public 方法,提高代码复用性;
  • 当发现类名比较难命名或类名笼统、冗长时,说明该类职责定义不够清晰;
  • 类中大量方法集中操作某几个属性时,可以考虑将这几个属性和方法拆分出去;

补充:在保证单一职责时,要避免过分拆分,否则会降低内聚性,影响代码可维护性。

1.1.3 举例:

 

/**
* 如果下面的用户信息类仅在一个场景中使用,则没有什么问题;
* 如果后面用户的地址信息在其他模块中使用时,就可以将地址信息进行拆分。
* 以及各个属性的操作方法都要进行聚合到一个类中,提高代码的维护性。
*/
data

面向接口编程详解(一)——思想基础(转)

本系列《面向接口编程详解》将分为三部分:
面向接口编程详解(一)——思想基础(已发布)
在这一篇中,将对接口及面向接口编程有个大致的介绍,着重在于思想上的讲解。
面向接口编程详解(二)——编程实例(已发布)
这一篇将结合一个实例“移动存储设备模拟”来让大家对面向接口编程有个直观印象。
面向接口编程详解(三)——模式研究(已发布)
讲解几个设计模式中的面向接口思想和基于.NET平台的分层架构中的面向接口思想,加深理解。…