程序员的持续学习之道

原文出处: ShareCore (@Justin_Programer)

 

我其实是一个悲观主义者,从开始成为一名程序员的那一天开始,我就对自己的职业充满着担忧。早期,我担忧的是我刚进入这一行,落后身边从事这一行多年的人太多,跟他们比,我一开始就处于“不公平“的起跑线上;二是当我稍微深入这行后,发现技术的道路充满了歧路和死胡同,稍不留神,就将落入再也跟不上技术进步的节奏,身边也充斥着类似的示例。

好在在这条路上,我找到了一个克服担忧的良方:学习,坚持不懈的学习!

人类最大的恐惧莫过于对未知的恐惧,而学习,是克服未知的一个最有效途径。那作为一个程序员,该如何才能做到坚持不懈的学习呢?我想主要有以下几点:

1. 不抗拒变化,跟踪变化

这里说的变化,更多指的是技术的变化。新技术永远层出不穷,如果你抗拒变化,或惧怕变化,在心里优势上就落后了一大截。很多程序员的技术道路越走越窄,当一门新技术来临时,他们从不去了解或研究,他们要么认为这是”换汤不换药“的”技术幌子“,不值得去研究,要么等着别人去研究,自己被动的接受别人的结论与成果。诚然,等待别人的研究结果也可行,但是,当身边没有人去研究呢?当研究的人不愿意提供给你他的研究结果呢?当别人的结论和结果是错误的呢?

当然,业界的新技术层出不穷,要去跟踪每一项新技术的变化也是不可能的,我的建议是尽量掌握基础的技术,越是基础的技术越是恒定。如计算机的体系架构,TCP,HTTP,各类编程范式,OOP,MVC架构等,都是好多年来没有发生过变化的技术了。许多新技术也是建立在他们上面,当你了解了这些基础的技术,建立在他们之上的新技术也就能很快掌握了,并能迅速而准确地对这些新技术作出“价值判断”。

技术的变化,其实也并不全是指业界的新技术来临,更多指的是,超出自己当前技术能力外,主动研究和选择的“新技术” ,主动丢弃老的套路和技术,不固步自封。见过很多的程序员,他们写了很多年的代码了,技术能力还停留在数据库层写一个Sql(存储过程)+前端调用上。为什么如此呢?因为自开始写代码起,这样简单粗暴的方式就可以解决他们面对的问题了。所以,当碰到新的问题,他们就继续沿用着这种方式,而从不去看看业界是不是有更合适的方案来解决。长此以往,他们的技术能力也就不会有任何的变化,工作十年,只是将第一年所学的技术重复十年而已

2. 书宜杂读,业宜精钻

建筑学家梁思成赴美留学,其父梁启超告诫说:你该挤出一部分时间学些常识性东西,特别是文学或人文科学,稍稍多用点工夫就能有大的收获。我深怕你因所学太专一,把多彩的生活弄得平平淡淡,生活过于单调,则生厌倦心理,厌倦一生即成苦恼之事……书宜杂读,业宜精钻。

学习本身应该是一件很快乐的事情,但如果只是一味地沉浸于专业学习之中,难免会将本来快乐的事情弄成平淡和单调,更可怕的是,由此产生厌倦心理,放弃学习。

所以,可以尽量跟随自己的兴趣,去更广泛地读书。历史,文学,心理学,哲学等等各方面的书都可以尝试去读,它们不仅丰富你的知识,更能让你在阅读中受到感动、教育和启迪。书读的更多更广泛,知道的事也就多,思路更加开阔,解决问题的能力也就能高于常人,从而反过来帮助到你专业能力的提升。

3. 投资团队,积极打造学习型团队

现代社会,难免的一点就是个人必须置身于群体之中,程序员更是如此。从群体心理学的角度来看,在群体里,个人的才智被削弱,异质性被同质性所吞没。由此,如果一个团队不爱学习,那么,其中的成员也很难坚持学习(个性和意志力特别强的人除外)。

如果你爱学习,请想办法让你的团队也变得爱学习,这样,你对学习的坚持将变得更加容易。或许你认为建立学习氛围,是团队领导的事情,跟自己无关。领导当然可以来做也需要来做这样的事情,但要明白的一点,学习这事,如果变成从上向下,就难免“政治化”了,容易失去它本身的意义。而从下往上,更能建立轻松和谐的学习环境。

一些软件设计原则

出自:http://blog.jobbole.com/685/

导读:酷壳网的陈皓给大家介绍了软件设计的一些原则,作者认为一个好的程序员通常由其操作技能、知识水平,经验层力和能力四个方面组成。软件设计的这些原则,每一个程序员都应该了解。相信大家从中能够从中学了解到一些设计原理方面的知识。
文章内容如下:

以前本站向大家介绍过一些软件开发的原则,比如优质代码的十诫和Unix传奇(下篇)中所以说的UNIX的设计原则。相信大家从中能够从中学了解到 一些设计原理方面的知识,正如我在《再谈“我是怎么招聘程序员”》中所说的,一个好的程序员通常由其操作技能、知识水平,经验层力和能力四个方面组成。在这 里想和大家说说设计中的一些原则,我认为这些东西属于长期经验总结出来的知识。这些原则,每一个程序员都应该了解。但是请不要教条主义,在使用的时候还是 要多多考虑实际情况。

下面这些原则,不单单只是软件开发,可以推广到其它生产活动中,甚至我们的生活中

Don’t Repeat Yourself(DRY)

DRY是一个最简单的法则,也是最容易被理解的。但它也可能是最难被应用的(因为要做到这样,我们需要在泛型设计上做相当的努力,这并不是一件容易 的事)。它意味着,当我们在两个或多个地方的时候发现一些相似的代码的时候,我们需要把他们的共性抽象出来形一个唯一的新方法,并且改变现有的地方的代码 让他们以一些合适的参数调用这个新的方法。

参考http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

Keep It Simple, Stupid (KISS)

KISS原则在设计上可能最被推崇的,在家装设计,界面设计,操作设计上,复杂的东西越来越被众人所BS了,而简单的东西越来越被人所认可,比如这些UI的设计和我们中国网页(尤其是新浪的网页) 者是负面的例子。“宜家”(IKEA)简约、效率的家居设计、生产思路;“微软”(Microsoft)“所见即所得”的理念;“谷歌”(Google) 简约、直接的商业风格,无一例外的遵循了“kiss”原则,也正是“kiss”原则,成就了这些看似神奇的商业经典。而苹果公司的iPhone/iPad 将这个原则实践到了极至。

把一个事情搞复杂是一件简单的事,但要把一个复杂的事变简单,这是一件复杂的事。

参考http://en.wikipedia.org/wiki/KISS_principle

Program to an interface, not an implementation

这是设计模式中最根本的哲学,注重接口,而不是实现,依赖接口,而不是实现。接口是抽象是稳定的,实现则是多种多样的。以后面我们会面向对象的SOLID原则中会提到我们的依赖倒置原则,就是这个原则的的另一种样子。还有一条原则叫Composition over inheritance(喜欢组合而不是继承),这两条是那23个经典设计模式中的设计原则。

Command-Query Separation (CQS)–命令-查询分离原则

查询:当一个方法返回一个值来回应一个问题的时候,它就具有查询的性质;
命令:当一个方法要改变对象的状态的时候,它就具有命令的性质;

通常,一个方法可能是纯的Command模式或者是纯的Query模式,或者是两者的混合体。在设计接口时,如果可能,应该尽量使接口单一化,保证 方法的行为严格的是命令或者是查询,这样查询方法不会改变对象的状态,没有副作用,而会改变对象的状态的方法不可能有返回值。也就是说:如果我们要问一个 问题,那么就不应该影响到它的答案。实际应用,要视具体情况而定,语义的清晰性和使用的简单性之间需要权衡。将Command和Query功能合并入一个 方法,方便了客户的使用,但是,降低了清晰性,而且,可能不便于基于断言的程序设计并且需要一个变量来保存查询结果。

在系统设计中,很多系统也是以这样原则设计的,查询的功能和命令功能的系统分离,这样有则于系统性能,也有利于系统的安全性。

参考http://en.wikipedia.org/wiki/Command-query_separation

You Ain’t Gonna Need It(YAGNI)

这个原则简而言之为——只考虑和设计必须的功能,避免过度设计。只实现目前需要的功能,在以后您需要更多功能时,可以再进行添加。
如无必要,勿增复杂性。

软件开发先是一场沟通博弈。

以前本站有一篇关于过度重构的文章,这个示例就是这个原则的反例。而,WebSphere的设计者就表示过他过度设计了这个产品。我们的程序员或是架构师在设计系统的时候,会考虑很多扩展性的东西,导致在架构与设计方面使用了大量折衷,最后导致项目失败。这是个令人感到讽刺的教训,因为本来希望尽可能延长项目的生命周期,结果反而缩短了生命周期。

参考http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It

Law of Demeter–迪米特法则

迪米特法则(Law of Demeter),又称“最少知识原则”(Principle of Least Knowledge),其来源于1987年荷兰大学的一个叫做Demeter的项目。Craig Larman把Law of Demeter又称作“不要和陌生人说话”。在《程序员修炼之道》中讲LoD的那一章叫作“解耦合与迪米特法则”。关于迪米特法则有一些很形象的比喻:

如果你想让你的狗跑的话,你会对狗狗说还是对四条狗腿说?

如果你去店里买东西,你会把钱交给店员,还是会把钱包交给店员让他自己拿?

和狗的四肢说话?让店员自己从钱包里拿钱?这听起来有点荒唐,不过在我们的代码里这几乎是见怪不怪的事情了。

对于LoD,正式的表述如下:
对于对象‘O’中一个方法‘M’,M应该只能够访问以下对象中的方法:

  • 1.对象O;
  • 2.与O直接相关的Component Object;
  • 3.由方法M创建或者实例化的对象;
  • 4.作为方法M的参数的对象。

在《Clean Code(代码整洁之道)》一书中,有一段Apache framework中的一段违反了LoD的代码:

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

这么长的一串对其它对象的细节,以及细节的细节,细节的细节的细节……的调用,增加了耦合,使得代码结构复杂、僵化,难以扩展和维护。

在《重构》一书中的代码的环味道中有一种叫做“Feature Envy”(依恋情结),形象的描述了一种违反了LoC的情况。Feature Envy就是说一个对象对其它对象的内容更有兴趣,也就是说老是羡慕别的对象的成员、结构或者功能,大老远的调用人家的东西。这样的结构显然是不合理的。 我们的程序应该写得比较“害羞”。不能像前面例子中的那个不把自己当外人的店员一样,拿过客人的钱包自己把钱拿出来。“害羞”的程序只和自己最近的朋友交 谈。这种情况下应该调整程序的结构,让那个对象自己拥有它羡慕的feature,或者使用合理的设计模式(例如Facade和Mediator)。

参考http://en.wikipedia.org/wiki/Principle_of_Least_Knowledge

面向对象的S.O.L.I.D原则

一般来说这是面向对象的五大设计原则,但是,我觉得这些原则可适用于所有的软件开发。

Single Responsibility Principle (SRP)–职责单一原则

关于单一职责原则,其核心的思想是:一个类,只做一件事,并把这件事做好,其只有一个引起它变化的原因。单一职 责原则可以看作是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。职责过多,可能引起它变化的原 因就越多,这将导致职责依赖,相互之间就产生影响,从而极大的损伤其内聚性和耦合度。单一职责,通常意味着单一的功能,因此不要为一个模块实现过多的功能 点,以保证实体只有一个引起它变化的原因。

Unix/Linux是这一原则的完美体现者。各个程序都独立负责一个单一的事。

Windows是这一原则的反面示例。几乎所有的程序都交织耦合在一起。

Open/Closed Principle (OCP)–开闭原则

关于开发封闭原则,其核心的思想是:模块是可扩展的,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的

对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。

对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

对于面向对象来说,需要你依赖抽象,而不是实现,23个经典设计模式中的“策略模式”就是这个实现。对于非面向对象编程,一些API需要你传入一个 你可以扩展的函数,比如我们的C语言的qsort()允许你提供一个“比较器”,STL中的容器类的内存分配,ACE中的多线程的各种锁。对于软件方面, 浏览器的各种插件属于这个原则的实践。

Liskov substitution principle (LSP)–里氏代换原则

软件工程大师Robert C. Martin把里氏代换原则最终简化为一句话:“Subtypes must be substitutable for their base types”。也就是,子类必须能够替换成它们的基类。即:子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。另外,不应该 在代码中出现if/else之类对子类类型进行判断的条件。里氏替换原则LSP是使代码符合开闭原则的一个重要保证。正是由于子类型的可替换性才使得父类 型的模块在无需修改的情况下就可以扩展。

这么说来,似乎有点教条化,我非常建议大家看看这个原则个两个最经典的案例——“正方形不是长方形”和“鸵鸟不是鸟”。通过这两个案例,你会明白 《墨子小取》中说的——“娣,美人也,爱娣,非爱美人也….盗,人也;恶盗,非恶人也。”——妹妹虽然是美人,但喜欢妹妹并不代表喜欢美人。盗贼是人,但 讨厌盗贼也并不代表就讨厌人类。这个原则让你考虑的不是语义上对象的间的关系,而是实际需求的环境

在很多情况下,在设计初期我们类之间的关系不是很明确,LSP则给了我们一个判断和设计类之间关系的基准:需不需要继承,以及怎样设计继承关系。

Interface Segregation Principle (ISP)–接口隔离原则

接口隔离原则意思是把功能实现在接口中,而不是类中,使用多个专门的接口比使用单一的总接口要好。

举个例子,我们对电脑有不同的使用方式,比如:写作,通讯,看电影,打游戏,上网,编程,计算,数据等,如果我们把这些功能都声明在电脑的抽类里 面,那么,我们的上网本,PC机,服务器,笔记本的实现类都要实现所有的这些接口,这就显得太复杂了。所以,我们可以把其这些功能接口隔离开来,比如:工 作学习接口,编程开发接口,上网娱乐接口,计算和数据服务接口,这样,我们的不同功能的电脑就可以有所选择地继承这些接口。

这个原则可以提升我们“搭积木式”的软件开发。对于设计来说,Java中的各种Event Listener和Adapter,对于软件开发来说,不同的用户权限有不同的功能,不同的版本有不同的功能,都是这个原则的应用。

Dependency Inversion Principle(DIP)–依赖倒置原则

高层模块不应该依赖于低层模块的实现,而是依赖于高层抽象。

举个例子,墙面的开关不应该依赖于电灯的开关实现,而是应该依赖于一个抽象的开关的标准接口,这样,当我们扩展程序的时候,我们的开关同样可以控制 其它不同的灯,甚至不同的电器。也就是说,电灯和其它电器继承并实现我们的标准开关接口,而我们的开关产商就可不需要关于其要控制什么样的设备,只需要关 心那个标准的开关标准。这就是依赖倒置原则。

这就好像浏览器并不依赖于后面的web服务器,其只依赖于HTTP协议。这个原则实在是太重要了,社会的分工化,标准化都是这个设计原则的体现。

参考http://en.wikipedia.org/wiki/Solid_(object-oriented_design)

Common Closure Principle(CCP)–共同封闭原则

一个包中所有的类应该对同一种类型的变化关闭。一个变化影响一个包,便影响了包中所有的类。一个更简短的说法是:一起修改的类,应该组合在一起(同 一个包里)。如果必须修改应用程序里的代码,我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。CCP原则就是把因为某个同样的原 因而需要修改的所有类组合进一个包里。如果2个类从物理上或者从概念上联系得非常紧密,它们通常一起发生改变,那么它们应该属于同一个包。

CCP延伸了开闭原则(OCP)的“关闭”概念,当因为某个原因需要修改时,把需要修改的范围限制在一个最小范围内的包里。

参考http://c2.com/cgi/wiki?CommonClosurePrinciple

Common Reuse Principle (CRP)–共同重用原则

包的所有类被一起重用。如果你重用了其中的一个类,就重用全部。换个说法是,没有被一起重用的类不应该被组合在一起。CRP原则帮助我们决定哪些类 应该被放到同一个包里。依赖一个包就是依赖这个包所包含的一切。当一个包发生了改变,并发布新的版本,使用这个包的所有用户都必须在新的包环境下验证他们 的工作,即使被他们使用的部分没有发生任何改变。因为如果包中包含有未被使用的类,即使用户不关心该类是否改变,但用户还是不得不升级该包并对原来的功能 加以重新测试。

CCP则让系统的维护者受益。CCP让包尽可能大(CCP原则加入功能相关的类),CRP则让包尽可能小(CRP原则剔除不使用的类)。它们的出发点不一样,但不相互冲突。

参考http://c2.com/cgi/wiki?CommonReusePrinciple

Hollywood Principle–好莱坞原则

好莱坞原则就是一句话——“don’t call us,we’ll call you.”。意思是,好莱坞的经纪人们不希望你去联系他们,而是他们会在需要的时候来联系你。也就是说,所有的组件都是被动的,所有的组件初始化和调用都 由容器负责。组件处在一个容器当中,由容器负责管理。

简单的来讲,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控。这也就是所谓“控制反转”的概念所在:

  • 1.不创建对象,而是描述创建对象的方式。
  • 2.在代码中,对象与服务没有直接联系,而是容器负责将这些联系在一起。

控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。

好莱坞原则就是IoC(Inversion of Control)或DI(Dependency Injection)的基础原则。这个原则很像依赖倒置原则,依赖接口,而不是实例,但是这个原则要解决的是怎么把这个实例传入调用类中?你可能把其声明 成成员,你可以通过构造函数,你可以通过函数参数。但是IoC可以让你通过配置文件,一个由Service Container 读取的配置文件来产生实际配置的类。但是程序也有可能变得不易读了,程序的性能也有可能还会下降。

参考
http://en.wikipedia.org/wiki/Hollywood_Principle
http://en.wikipedia.org/wiki/Inversion_of_Control

High Cohesion & Low/Loose coupling & –高内聚,低耦合

这个原则是UNIX操作系统设计的经典原则,把模块间的耦合降到最低,而努力让一个模块做到精益求精。

  • 内聚:一个模块内各个元素彼此结合的紧密程度
  • 耦合:一个软件结构内不同模块之间互连程度的度量

内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。

参考
http://en.wikipedia.org/wiki/Coupling_(computer_science)
http://en.wikipedia.org/wiki/Cohesion_(computer_science)

Convention over Configuration(CoC)–惯例优于配置原则

简单点说,就是将一些公认的配置方式和信息作为内部缺省的规则来使用。例如,Hibernate的映射文件,如果约定字段名和类属性一致的话,基本 上就可以不要这个配置文件了。你的应用只需要指定不convention的信息即可,从而减少了大量convention而又不得不花时间和精力啰里啰嗦 的东东。配置文件很多时候相当的影响开发效率。

Rails中很少有配置文件(但不是没有,数据库连接就是一个配置文件),Rails的fans号称期开发效率是java开发的10倍,估计就是这 个原因。Maven也使用了CoC原则,当你执行mvn -compile命令的时候,不需要指源文件放在什么地方,而编译以后的class文件放置在什么地方也没有指定,这就是CoC原则。

参考http://en.wikipedia.org/wiki/Convention_over_Configuration

Separation of Concerns (SoC)–关注点分离

SoC是计算机科学中最重要的努力目标之一。这个原则,就是在软件开发中,通过各种手段,将问题的各个关注点分开。如果一个问题能分解为独立且较小 的问题,就是相对较易解决的。问题太过于复杂,要解决问题需要关注的点太多,而程序员的能力是有限的,不能同时关注于问题的各个方面。正如程序员的记忆力 相对于计算机知识来说那么有限一样,程序员解决问题的能力相对于要解决的问题的复杂性也是一样的非常有限。在我们分析问题的时候,如果我们把所有的东西混 在一起讨论,那么就只会有一个结果——乱。

我记得在上一家公司有一个项目,讨论就讨论了1年多,项目本来不复杂,但是没有使用SoC,全部的东西混为一谈,再加上一堆程序员注入了各种不同的观点和想法,整个项目一下子就失控了。最后,本来一个1年的项目做了3年。

实现关注点分离的方法主要有两种,一种是标准化,另一种是抽象与包装。标准化就是制定一套标准,让使用者都遵守它,将人们的行为统一起来,这样使用 标准的人就不用担心别人会有很多种不同的实现,使自己的程序不能和别人的配合。Java EE就是一个标准的大集合。每个开发者只需要关注于标准本身和他所在做的事情就行了。就像是开发镙丝钉的人只专注于开发镙丝钉就行了,而不用关注镙帽是怎 么生产的,反正镙帽和镙丝钉按标来就一定能合得上。不断地把程序的某些部分抽像差包装起来,也是实现关注点分离的好方法。一旦一个函数被抽像出来并实现 了,那么使用函数的人就不用关心这个函数是如何实现的,同样的,一旦一个类被抽像并实现了,类的使用者也不用再关注于这个类的内部是如何实现的。诸如组 件,分层,面向服务,等等这些概念都是在不同的层次上做抽像和包装,以使得使用者不用关心它的内部实现细节。
说白了还是“高内聚,低耦合”。

参考http://sulong.me/archives/99

Design by Contract (DbC)–契约式设计

DbC的核心思想是对软件系统中的元素之间相互合作以及“责任”与“义务”的比喻。这种比喻从商业活动中“客户”与“供应商”达成“契约”而得来。例如:
供应商必须提供某种产品(责任),并且他有权期望客户已经付款(权利)。
客户必须付款(责任),并且有权得到产品(权利)。

契约双方必须履行那些对所有契约都有效的责任,如法律和规定等。

同样的,如果在程序设计中一个模块提供了某种功能,那么它要:
期望所有调用它的客户模块都保证一定的进入条件:这就是模块的先验条件(客户的义务和供应商的权利,这样它就不用去处理不满足先验条件的情况)。

保证退出时给出特定的属性:这就是模块的后验条件——(供应商的义务,显然也是客户的权利)。

在进入时假定,并在退出时保持一些特定的属性:不变式。

契约就是这些权利和义务的正式形式。我们可以用“三个问题”来总结DbC,并且作为设计者要经常问:

  • 它期望的是什么?
  • 它要保证的是什么?
  • 它要保持的是什么?

根据Bertrand Meyer氏提出的DBC概念的描述,对于类的一个方法,都有一个前提条件以及一个后续条件,前提条件说明方法接受什么样的参数数据等,只有前提条件得到 满足时,这个方法才能被调用;同时后续条件用来说明这个方法完成时的状态,如果一个方法的执行会导致这个方法的后续条件不成立,那么这个方法也不应该正常 返回。

现在把前提条件以及后续条件应用到继承子类中,子类方法应该满足:

  • 1.前提条件不强于基类.
  • 2.后续条件不弱于基类.

换句话说,通过基类的接口调用一个对象时,用户只知道基类前提条件以及后续条件。因此继承类不得要求用户提供比基类方法要求的更强的前提条件,亦 即,继承类方法必须接受任何基类方法能接受的任何条件(参数)。同样,继承类必须顺从基类的所有后续条件,亦即,继承类方法的行为和输出不得违反由基类建 立起来的任何约束,不能让用户对继承类方法的输出感到困惑。

这样,我们就有了基于契约的LSP,基于契约的LSP是LSP的一种强化。

参考http://en.wikipedia.org/wiki/Design_by_contract

Acyclic Dependencies Principle (ADP)–无环依赖原则

包之间的依赖结构必须是一个直接的无环图形,也就是说,在依赖结构中不允许出现环(循环依赖)。如果包的依赖形成了环状结构,怎么样打破这种循环依 赖呢?有2种方法可以打破这种循环依赖关系:第一种方法是创建新的包,如果A、B、C形成环路依赖,那么把这些共同类抽出来放在一个新的包D里。这样就把 C依赖A变成了C依赖D以及A依赖D,从而打破了循环依赖关系。第二种方法是使用DIP(依赖倒置原则)和ISP(接口分隔原则)设计原则。

无环依赖原则(ADP)为我们解决包之间的关系耦合问题。在设计模块时,不能有循环依赖。

参考http://c2.com/cgi/wiki?AcyclicDependenciesPrinciple

上面这些原则可能有些学院派,也可能太为理论,我在这里说的也比较模糊和简单,这里只是给大家一个概貌,如果想要了解更多的东西,大家可以多google一下。

不过这些原则看上去都不难,但是要用好却并不那么容易。要能把这些原则用得好用得精,而不教条,我的经验如下:(我以为这是一个理论到应用的过程)

  • 1.你可以先粗浅或是表面地知道这些原则。
  • 2.但不要急着马上就使用。
  • 3.在工作学习中观察和总结别人或自己的设计。
  • 4.再回过头来了回顾一下这些原则,相信你会有一些自己的心得。
  • 5.有适度地去实践一下。
  • 6.Goto第 3步。

好的程序设计原则

好的编程原则跟好的系统设计原则和技术实施原则有着密切的联系。下面的这些编程原则在过去的这些年里让我成为了一名优秀的程序员,我相信,这些原则对任何一个开发人员来说,都能让他的编程能力大幅度的提高,能让他开发出可维护性更强、缺陷更少的程序。

我不要自我重复 — 这也许是在编程开发这最最基本的一个信条,就是要告诉你不要出现重复的代码。我们很多的编程结构之所以存在,就是为了帮助我们消除重复(例如,循环语句,函数,类,等等)。一旦程序里开始有重复现象的出现(例如很长的表达式、一大堆的语句,但都是为了表达相同的概念),你就需要对代码进行一次新的提炼,抽象。
http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

提炼原则 — 跟“不要自我重复原则”相关,这一原则是说“程序中任何一段具有功能性的代码在源代码文件中应该唯一的存在。”
http://en.wikipedia.org/wiki/Abstraction_principle_(programming)

保持简单 — 简单化(避免复杂)永远都应该是你的头等目标。简单的程序让你写起来容易,产生的bug更少,更容易维护修改。
http://en.wikipedia.org/wiki/KISS_principle

不要开发你目前用不到的功能 — 除非你真正需要用到它,否则不要轻易加上那些乱七八糟用不到的功能。
http://en.wikipedia.org/wiki/YAGNI

用最简单的方法让程序跑起来 — 在开发时有个非常好的问题你需要问问自己,“怎样才能最简单的让程序跑起来?”这能帮助我们在设计时让程序保持简单。
http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html

不要让我动脑子 — 这实际上是Steve Krug 关于web界面操作的一本书的书名,但也适用于编程。主旨是,程序代码应该让人们花最小的努力就能读懂和理解。如果一段程序对于阅读者来说需要花费太多的努力才能理解,那它很可能需要进一步简化。
http://www.sensible.com/dmmt.html

开放/封闭原则 — 程序里的实体项(类,模块,函数等)应该对扩展行为开放,对修改行为关闭。换句话说,不要写允许别人修改的类,应该写能让人们扩展的类。
http://en.wikipedia.org/wiki/Open_Closed_Principle

为维护者写程序 — 任何值得你编写的程序在将来都是值得你去维护的,也许由你维护,也许由他人。在将来,当你不得不维护这些程序时,你对这些代码的记忆会基本上跟一个陌生人一样,所以,你最好还是当成一直在给别人写程序。一个有助于你记住这个原则的办法是“写程序时时刻记着,这个将来要维护你写的程序的人是一个有严重暴力倾向,并且知道你住在哪里的精神变态者”。
http://c2.com/cgi/wiki?CodeForTheMaintainer

最少意外原则 — 最少意外原则通常是使用在用户界面设计上,但这个原则同样适用于编写程序。程序代码应尽可能的不要让阅读者感到意外。也就是说应该遵循编码规范和常见习惯,按照公认的习惯方式进行组织和命名,不符常规的编程动作应该尽可能的避免。
http://en.wikipedia.org/wiki/Principle_of_least_astonishment

单一职责原则 — 一个代码组件(例如类或函数)应该只执行单一的预设的任务。
http://en.wikipedia.org/wiki/Single_responsibility_principle

最小化耦合关系 — 一个代码片段(代码块,函数,类等)应该最小化它对其它代码的依赖。这个目标通过尽可能少的使用共享变量来实现。“低耦合是一个计算机系统结构合理、设计优秀的标志,把它与高聚合特征联合起来,会对可读性和可维护性等重要目标的实现具有重要的意义。”
http://en.wikipedia.org/wiki/Coupling_(computer_programming)

最大化内聚性 — 具有相似功能的代码应该放在同一个代码组件里。
http://en.wikipedia.org/wiki/Cohesion_(computer_science)

隐藏实现细节 — 隐藏实现细节能最小化你在修改程序组件时产生的对那些使用这个组件的其它程序模块的影响。
http://en.wikipedia.org/wiki/Information_Hiding

笛米特法则(Law of Demeter) — 程序组件应该只跟它的直系亲属有关系(例如继承类,内包含的对象,通过参数入口传入的对象等。)
http://en.wikipedia.org/wiki/Law_of_Demeter

避免过早优化 — 只有当你的程序没有其它问题,只是比你预期的要慢时,你才能去考虑优化工作。只有当其它工作都做完后,你才能考虑优化问题,而且你只应该依据经验做法来优化。“对于小幅度的性能改进都不该考虑,要优化就应该是97%的性能提升:过早优化是一切罪恶的根源”—Donald Knuth。
http://en.wikipedia.org/wiki/Program_optimization

代码复用 — 这不是非常核心的原则,但它跟其它原则一样非常有价值。代码复用能提高程序的可靠性,节省你的开发时间。
http://en.wikipedia.org/wiki/Code_reuse

职责分离 — 不同领域的功能应该由完全不同的代码模块来管理,尽量减少这样的模块之间的重叠。 http://en.wikipedia.org/wiki/Separation_of_concerns

拥抱变化 — 这是Kent Beck的一本书的副标题,它也是极限编程和敏捷开发方法的基本信条之一。很多的其它原则都基于此观念:面对变化,欢迎变化。事实上,一些经典的软件工程原则,例如最小化耦合,就是为了让程序更容易面对变化。不论你是否采用了极限编程方法,这个原则对你的程序开发都有重要意义。http://www.amazon.com/gp/product/0321278658

[英文原文:The Principles of Good Programming ]
这和《代码大全》上的总结基本一致

C#、PHP、Python 运算符的优先级

C#、PHP、Python 运算符的优先级

C#  运算符优先级

优先级
类别
运算符
1
基本
(x) x.y f(x) a[x] x++ x――new typeof sizeof checked unchecked
2
单目
+ - ! ~ ++x ――x (T)x
3
乘法与除法
* / %
4
加法与减法
+ -
5
移位运算
<< >>
6
关系运算
< > < = >=
7
条件等
= = ! =
8
位逻辑与
&
9
位逻辑异或
^
10
位逻辑或
|
11
条件与
&&
12
条件或
13
条件
?:
14
赋值
= *= /= %= += -= <<= >>= &= ^= |=

 

上表源自:  http://baike.baidu.com/view/262524.htm#4

C# 提供大量运算符,这些运算符是指定在表达式中执行哪些操作的符号。             ==, !=, &lt;, &gt;, &lt;=, &gt;=, binary +, binary -, ^, &amp;,’ xml:space=”preserve”>整型运算包括 ==、!=、<、>、<=、>=、binary +、binary -、^、& |~, ++, –, and sizeof() are generally allowed on enumerations.’ xml:space=”preserve”>、~、++、– 和 sizeof(),通常在枚举时允许这些运算。  overloaded by the user, thus changing their meaning when applied to a user-defined type.’ xml:space=”preserve”>此外,很多运算符可被用户重载,由此在应用到用户定义的类型时更改这些运算符的含义。

下表列出了按发型版本不同的 C# 运算符:

 

PHP运算符优先级

 

 
结合方向 运算符 附加信息
非结合 clone new clone 和 new
[ array()
非结合 ++ -- 递增/递减运算符
非结合 ~ - (int) (float) (string) (array) (object) (bool) @ 类型
非结合 instanceof 类型
右结合 ! 逻辑操作符
* / % 算术运算符
+ - . 算术运算符 和 字符串运算符
<< >> 位运算符
非结合 < <= > >= <> 比较运算符
非结合 == != === !== 比较运算符
& 位运算符 和 引用
^ 位运算符
| 位运算符
&& 逻辑运算符
|| 逻辑运算符
? : 三元运算符
= += -= *= /= .= %= &= |= ^= <<= >>= 赋值运算符
and 逻辑运算符
xor 逻辑运算符
or 逻辑运算符
, 多处用到

 

 

Python 运算符优先级

 

这个表给出Python的运算符优先级(从低到高).

从最低的优先级(最松散地结合)到最高的优先级(最紧密地结合)。

这意味着在一个表达式中,Python会首先计算表中较下面的运算符,然后在计算列在表上部的运算符。

 
运算符 描述
lambda Lambda表达式
or 布尔“或”
and 布尔“与”
not x 布尔“非”
in,not in 成员测试
is,is not 同一性测试
<,<=,>,>=,!=,== 比较
| 按位或
^ 按位异或
& 按位与
<<,>> 移位
+,- 加法与减法
*,/,% 乘法、除法与取余
+x,-x 正负号
~x 按位翻转
** 指数
x.attribute 属性参考
x[index] 下标
x[index:index] 寻址段
f(arguments...) 函数调用
(experession,...) 绑定或元组显示
[expression,...] 列表显示
{key:datum,...} 字典显示
'expression,...' 字符串转换

 

上两表源自:  http://tool.oschina.net/commons?type=6#php_

 

一些适合学习/服务器/VPS和开发的 Linux, BSD 发行版本


发行归类: Other OS

  • 基于何种发行: Independent
  • 来源: Netherlands
  • 处理器架构: i386
  • 桌面: EDE, JWM
  • 类型: Education
  • 状态: 活跃发展中

MINIX是一份像UNIX的计算机操作系统,它基于微内核架构。它极其地小,运行于内核模式的部分仅约5000行可执行代码,而运行于用户模式的部分被分解为小型且独立的模块,从而提高系统可靠性。它最初被设计为一份教学工具,但最新版本的MINIX也面向嵌入式系统及低端笔记本电脑。据其声称,MINIX仍在开发中,并且还远不及BSD或Linux那样成熟。它遵循一份BSD类型的许可证来发布。


  • 发行归类: Linux
  • 基于何种发行: Independent (originally forked from Damn Small)
  • 来源: USA
  • 处理器架构: armhf, i486
  • 桌面: Fluxbox, flwm, Hackedbox, IceWM, JWM, Openbox
  • 类型: Desktop, Live Medium, Old Computers
  • 状态: 活跃发展中

Tiny Core Linux是一份12兆字节的图形化Linux桌面。它基于Linux 2.6内核、BusyBox、Tiny X、Fltk、Flwm。其核心完全运行于内存中并且启动非常快。用户对需要支持哪些应用程序和/或额外硬件拥有完全的控制,无论系统是面向台式机、上网机、应用服务器;这可以从该项目的在线软件仓库中进行选择。


  • 发行归类: Linux
  • 基于何种发行: Fedora, Red Hat
  • 来源: USA
  • 处理器架构: i386, x86_64
  • 桌面: GNOME, KDE
  • 类型: Desktop, Live Medium, Server
  • 状态: 活跃发展中

作为一个团体,CentOS是一个开源软件贡献者和用户的社区。典型的CentOS用户包括这样一些组织和个人,他们并不需要专门的商业支持就能开展成功的业务。CentOS是Red Hat Enterprise Linux的100%兼容的重新组建,并完全符合Red Hat的再发行要求。CentOS面向那些需要企业级操作系统稳定性的人们,而且并不涉及认证和支持方面的开销。


  • 发行归类: Linux
  • 基于何种发行: Arch
  • 来源: Austria, Germany, France
  • 处理器架构: i686, x86_64
  • 桌面: Cinnamon, Enlightenment, KDE, LXDE, MATE, Openbox, Xfce
  • 类型: Desktop, Live Medium
  • 状态: 活跃发展中

Manjaro Linux是快速的、用户友好的、面向桌面的、基于Arch Linux的操作系统。它的一些显著特性包括:一份直观的安装程序、自动硬件检测、稳定的滚动式发布模式、对安装多个内核的支持、用于管理图形卡的特别Bash脚本、高度的桌面可配置性。Manjaro Linux提供Xfce和Openbox桌面作为核心选项,并为高级用户提供一份最小主义的Net版本。用户还可以获得社区支持的GNOME 3/Cinnamon及KDE版本。Manjaro的社区论坛可提供帮助并充满活力,用户受益其中。


  • 发行归类: BSD
  • 基于何种发行: FreeBSD
  • 来源: France
  • 处理器架构: i386, x86_64
  • 桌面:
  • 类型: NAS
  • 状态: 活跃发展中

FreeNAS是一份基于FreeBSD的小型操作系统,它提供免费的网络附加存储(NAS)服务(CIFS、FTP、NFS)。


  • 发行归类: BSD
  • 基于何种发行: FreeBSD
  • 来源: Switzerland
  • 处理器架构: i386
  • 桌面:
  • 类型: Firewall
  • 状态: 活跃发展中

m0n0wall计划的目标是创建一份完整的、内置的防火墙软件包,当它配合PC使用时,能够提供商用防火墙机器的所有重要功能(连同易用性在内),而其价钱却只是后者的一小部分(因为m0n0wall是自由软件)。m0n0wall基于FreeBSD的一个精简版本,并带有一个web服务器(thttpd)、PHP以及其他一些实用工具。整套系统配置存储于单个的XML文本文件以对系统透明。m0n0wall很可能是首个拥有用PHP实现的启动配置的UNIX系统,而通常这是依靠shell脚本的,此外,它把整个系统配置都用XML格式存储。

 


  • 发行归类: BSD
  • 基于何种发行: FreeBSD
  • 来源: Netherlands
  • 处理器架构: i386, x86_64
  • 桌面:
  • 类型: NAS
  • 状态: 活跃发展中

NAS4Free是基于FreeBSD的嵌入式开源NAS(网络附属存储)发行。NAS4Free支持跨越多种操作系统的共享,包括Windows、Apple、类UNIX系统。NAS4Free在多数家庭及企业环境中都易于安装,并且能在网络上方便地管理和共享海量数据。NAS4Free还集成了很多不同的流特性,以与网络上的其他设备共享多媒体数据。NAS4Free包含ZFS v28(RAIDZ、RAIDZ2、RAIDZ3),软件RAID(0、1、5),磁盘加密,S.M.A.R.T或邮件报告,并支持以下的多种协议:CIFS(samba)、FTP、NFS、TFTP、AFP、RSYNC、Unison、iSCSI(发起者及目标)、HAST、CARP、Bridge、UPnP、BitTorrent。所有功能都可通过网页界面来高度定制。

 


  • 发行归类: Linux
  • 基于何种发行: Debian
  • 来源: Germany
  • 处理器架构: i686, x86_64
  • 桌面:
  • 类型: NAS
  • 状态: 活跃发展中

OpenMediaVault是基于Debian GNU/Linux的网络连接存储(NAS)解决方案。它包含SSH、(S)FTP、SMB/CIFS、DAAP媒体服务器、rsync、BitTorrent等很多种服务。得益于模块化的设计,它可以通过插件来扩展。OpenMediaVault主要被设计用于家用环境或小型家庭办公室,但却不局限于此类。它是一份简单和易于使用的、开箱即用的解决方案,能让所有人无需很深的知识就能安装并管理一套网络连接存储。


  • 发行归类: Linux
  • 基于何种发行: Independent
  • 来源: United Kingdom
  • 处理器架构: i686, x86_64
  • 桌面:
  • 类型: Firewall
  • 状态: 活跃发展中

Smoothwall是一系列的Internet安全产品,它被设计用来保护你的用户和网络免受外来的攻击。Smoothwall Express基于Linux操作系统。对安全系统而言Linux是一个理想的选择,它是可信赖的、安全的、具有高度可定制性并可免费获得其开放源码。Smoothwall包含一套经过加固的GNU/Linux操作系统,因此,无需再单个地安装其他系统。Smoothwall被设计为易于使用,并通过基于web的图形用户界面来进行配置。它并不要求用户具有Linux方面的知识就能安装和使用。


  • 发行归类: Linux
  • 基于何种发行: Debian (Stable)
  • 来源: USA
  • 处理器架构: i386, x86_64
  • 桌面:
  • 类型: Server
  • 状态: 活跃发展中

TurnKey Linux是基于Debian的虚拟应用程序库,它将一些最好的开放源码软件集成到完备可用的解决方案中。每一个虚拟应用程序都为易用性进行了优化,并能在数分钟内就部署在裸机、虚拟机及云中。每一个虚拟应用都可以光盘镜像或是虚拟机镜像的形式获得,而这份仍在增长的应用列表包括Bugzilla、Django、Drupal、File Server、Joomla、LAMP、Magento、Mantis、MediaWiki、MoinMoin、Moodle、MovableType、MySQL、Openbravo、phpBB、PostgreSQL、ProjectPier、Rails、Revision Control、StatusNet、Apache Tomcat、Torrent Server、Trac、TWiki、vtiger、WordPress、Zimra及其他。


  • 发行归类: Linux
  • 基于何种发行: Arch
  • 来源: Canada
  • 处理器架构: i686, x86_64
  • 桌面: i3, Openbox
  • 类型: Desktop, Live Medium
  • 状态: 活跃发展中

ArchBang Linux是基于Arch Linux的轻量级发行。使用Openbox窗口管理器,它快捷并保持最新,既适合于桌面又适合于便携式系统。


  • 发行归类: Linux
  • 基于何种发行: Fedora, CentOS
  • 来源: USA
  • 处理器架构: i386, x86_64
  • 桌面:
  • 类型: Server
  • 状态: 活跃发展中

SME Server(最初叫作e-smith)由Joseph和Kim Morrison创立于1999年1月。同年4月公司推出了他们旗舰软件产品的首个版本——e-smith服务器及网关。到年底时,已经有数千的e-smith服务器运行在从斐济到芬兰的各个国家。关于e-smith的消息很快地流传在开发人员和系统集成人员中,而他们需要的正是面向小型企业用户的牢固易用的服务器。2001年7月,e-smith公司被Mitel Networks收购,2004年9月又被Lycoris收购,并且该项目目前还得到了Resource Strategies公司的赞助。


  • 发行归类: Linux
  • 基于何种发行: Debian
  • 来源: Germany
  • 处理器架构: i386, x86_64
  • 桌面: GNOME, KDE
  • 类型: Desktop, Live Medium
  • 状态: 活跃发展中

Tanglu是基于Debian的Linux发行,它旨在向普通用户和发烧友提供最佳的桌面体验。与Debian GNU/Linux相比,Tanglu计划提供大量用户友好的、面向桌面的特性,比如可用的新软件、对额外固件的缺省包含,以及基于时间的、规律化的发布周期。


  • 发行归类: Linux
  • 基于何种发行: Independent
  • 来源: Germany
  • 处理器架构: i586, x86_64
  • 桌面: Blackbox, GNOME, IceWM, KDE, LXDE, Openbox, WMaker, Xfce
  • 类型: Desktop, Server, Live Medium, Raspberry Pi
  • 状态: 活跃发展中

openSUSE项目是Novell公司资助的社区计划。为在方方面面促进Linux的普及应用,该计划提供了对openSUSE这份完整Linux发行的免费、简便的获取访问。openSUSE项目有三个主要目标:让openSUSE成为任何人都能最容易获得且最广泛使用的Linux发行,利用开源软件的联合来使openSUSE成为世界上可用性最强的Linux发行及新手和资深Linux用户们的桌面环境,显著地简化并开放其开发及打包过程以使openSUSE成为Linux开发人员及软件提供商所选择的平台。


  • 发行归类: Linux
  • 基于何种发行: Debian (Stable)
  • 来源: United Kingdom
  • 处理器架构: i486, i686, x86_64
  • 桌面: Openbox
  • 类型: Desktop, Netbooks, Old Computers
  • 状态: 活跃发展中

CrunchBang Linux是一份基于Debian的发行,其特色在于轻量级的Openbox窗口管理器和GTK+应用程序。该发行从一份最小的Debian系统创建,并被定制为可以提供速度和功能两方面的一个良好均衡。CrunchBang Linux目前可以一份自启动运行光盘获得,然而为获得其最佳性能建议还是安装到硬盘上使用。


  • 发行归类: Linux
  • 基于何种发行: Independent
  • 来源: Australia
  • 处理器架构: i386
  • 桌面: JWM, Openbox
  • 类型: Desktop, Old Computers, Live Medium, Netbooks
  • 状态: 活跃发展中

是的,Puppy Linux是另外一种Linux发行。它的不同之处在于,Puppy是格外的小,然而又充满了特性。Puppy能从64M的存储设备启动,并且,整套系统都能在内存中运行。有很多自启动运行光盘的Linux发行,它们需要不停地从光盘读取数据才能运行,Puppy与它们不一样,Puppy整个装载在内存中。这意味着,所有的应用程序一眨眼的功夫就能启动,并且立即对用户的输入作出响应。Puppy Linux能从flash卡或者是任何的USB存储设备启动(这是flash-Puppy),或者光盘(这是live-Puppy),或者Zip disk及LS/120/240 Superdisk(这是zippy-Puppy),或者软盘(这是floppy-Puppy),或者硬盘(这是hard-Puppy)。它甚至可以使用一张多区段烧录的CD-R/DVD-R以将所有内容保存回CD/DVD中。


  • 发行归类: Linux
  • 基于何种发行: Debian, KNOPPIX
  • 来源: USA
  • 处理器架构: i386
  • 桌面: JWM, Fluxbox
  • 类型: Old Computers, Live Medium
  • 状态: 活跃发展中

Damn Small Linux是一套基于业务卡(50M字节)可启动光盘的Linux发行。尽管它的个头如此之小,它努力成为一份可用并且易用的桌面。Damn Small Linux的桌面几乎是完整的一套,包括xmms(支持mp3和mpeg)、FTP客户端、基于links的web浏览器、电子制表软件、电子邮件程序、英语拼写检查、字处理器、三个编辑器(nedit、nvi及类似emacs的zile)、xpdf阅读器、worker文件管理器、naim(支持AIM、ICQ和IRC)、VNCviewer、SSH/SCP服务器和客户端、DHCP客户端、PPP及PPPoE、web服务器、计算器、Fluxbox窗口管理器、系统监视软件、USB支持,并且它很快就将拥有PCMCIA支持。如果你喜欢Damn Small Linux,你可以安装到你的硬盘上。由于所有的软件都是小巧型的,所以它对老旧的硬件会是一个很好的选择。


  • 发行归类: Linux
  • 基于何种发行: Independent
  • 来源: Switzerland
  • 处理器架构: armhf, i386, x86_64
  • 桌面: XBMC Media Centre
  • 类型: Multimedia, Raspberry Pi
  • 状态: 活跃发展中

OpenELEC是基于Linux创建的嵌入式操作系统,其专用目的在于运行XBMC,而这是开放源码的娱乐媒体中心。OpenELEC的理念是让人们在使用他们的家庭影院个人电脑(HTPC)时,就像使用任何其它连接到电视机的设备一样,比如DVD播放器或者Sky box。OpenELEC并不需要人们去维护一套完整的操作系统、进行系统设置并安装软件包以成为一套综合多媒体中心;它被设计为易于安装、管理和使用,从而使用它更像运行一台机顶盒而不是一部功能完善的计算机。


  • 发行归类: Linux
  • 基于何种发行: Fedora
  • 来源: Global
  • 处理器架构: i586, i686, x86_64
  • 桌面:
  • 类型: Server, Security
  • 状态: 活跃发展中

Openwall GNU/*/Linux(简称Owl)是一份小型的安全增强的Linux发行,它面向服务器、电器以及虚拟电器。支持SSH远程访问的Owl自启动运行光盘可用于修复或者安装系统(哪怕安装的不是Owl)。其另一种次要的应用场合则在于操作系统和/或计算机安全课程培训,这些课程可以从Owl的简单结构及完整环境得益。

多种常见软件系统缩写

BPM(Business Process Management):业务流程管理

也称做商业流程管理。一套达成企业各种业务环节整合的全面管理模式。其中的Business并不局限于商业,它泛指各种组织中的活动:从商业企业到政府机构、非营利团体等等,因此,普遍共识是对应于更加中性的“业务”一词,例如:业务流程管理(Business Process Management, BPM)、业务流程再造(Business Process Reengineering, BPR)等。Business Process Modeling,即业务流程建模,是对业务流程进行表述的方式,它是过程分析与重组的重要基础。

 

CRM(Customer Relationship Management):客户关系管理

是一个不断加强与顾客交流,不断了解顾客需求,并不断对产品及服务进行改进和提高以满足顾客的需求的连续的过程。其内含是企业利用信息技(IT)术和互联网技术实现对客户的整合营销,是以客户为核心的企业营销的技术实现和管理实现。客户关系管理注重的是与客户的交流,企业的经营是以客户为中心,而不是传统的以产品或以市场为中心。为方便与客户的沟通,客户关系管理可以为客户提供多种交流的渠道。

 

CMS(Content Management System):内容管理系统

它具有许多基于模板的优秀设计,可以加快网站开发的速度和减少开发的成本。CMS的功能并不只限于文本处理,它也可以处理图片、Flash动画、声像流、图像甚至电子邮件档案。

 

EIP(Enterprise Information Portal): 企业信息门户

是指在Internet的环境下,把各种应用系统、数据资源和互联网资源统一集成到企业信息门户之下,根据每个用户使用特点和角色的不同,形成个性化的应用界面,并通过对事件和消息的处理、传输把用户有机地联系在一起。

 

ERP(Enterprise Resource Planning):企业资源计划系统

又译企业资源规划,简单地说,ERP是“一个大型模块化、集成性的流程导向系统,集成企业内部财务会计、制造、进销存等信息流,快速提供决策信息,提升企业的营运绩效与快速反应能力。”它是e化企业的后台心脏与骨干。任何前台的应用系统包括EC、CRM、SCM等都以它为基础。
一般ERP软件强调如下之系统集成。
ERP主要的模块有:
生产管理:工程、材料清单(Bill Of Material)、调度、产能、工作流管理、质量控制、成本管理、生产过程、生产工程、生产流程、生产配置
进销存货管理:库存、订单输入、采购、供应商调度、货物检查、付款请求处理、佣金计算
财务管理及会计项目:总帐、现金管理、应付帐款管理、应收帐款管理、票据资金管理、固定资产管理
成本管理:账单、时间和支出、活动管理
人力资源管理:人力资源、薪金名册、培训管理、员工班别和出勤管理、津贴、劳健保、绩效考核
供应链管理:和客户、供应商、员工之间的各种自服务接口

 

GIS(Geographic Information System):地理信息系统

又称为“地学信息系统”。它是一种特定的十分重要的空间信息系统。它是在计算机硬、软件系统支持下,对整个或部分地球表层(包括大气层)空间中的有关地理分布数据进行采集、储存、管理、运算、分析、显示和描述的技术系统。

 

MIS(Management Information System):管理信息系统

是一个由人、计算机及其他外围设备等组成的能进行信息的收集、传递、存贮、加工、维护和使用的系统。利用现代计算机及网络通讯技术加强企业的信息管理,通过对企业拥有的人力、物力、财力、设备、技术等资源的调查了解,建立正确的数据,加工处理并编制成各种信息资料及时提供给管理人员,以便进行正确的决策,不断提高企业的管理水平和经济效益。

 

OA(Office Automation):办公自动化

是现代利用电脑进行全自动的办公,目的是提高效率。

 

SCM(Supply Chain Management):供应链管理

把公司的制造过程、库存系统和供应商产生的数据合并在一起,从一个统一的视角展示产品建造过程的各种影响因素。对整个供应链(从供货商,制造商,分销商到消费者)的各个环节进行综合管理,例如从采购、物料管理、生产、配送、营销到消费者的整个供应链的货物流、信息流和资金流,把物流与库存成本降到最小。供应链是企业赖以生存的商业循环系统,是企业电子商务管理中最重要的课题。

 

WfMS(Workflow Management System):工作流管理系统

工作流(Workflow),是对工作流程及其各操作步骤之间业务规则的抽象、概括、描述。工作流建模,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰当的模型进行表示并对其实施计算。工作流要解决的主要问题是:为实现某个业务目标,在多个参与者之间,利用计算机,按某种预定规则自动传递文档、信息或者任务。工作流管理系统(Workflow Management System, WfMS)的主要功能是通过计算机技术的支持去定义、执行和管理工作流,协调工作流执行过程中工作之间以及群体成员之间的信息交互。工作流需要依靠工作流管理系统来实现。

 

WMS(Warehouse Management System):仓储管理系统

对物料存放空间进行管理的软件,区别于库存管理。其功能主要有两方面,一为通过在系统中设定一定的仓库仓位结构对物料具体空间位置的定位,二为通过在系统中设定一些策略对物料入库\出库\库内等作业流程进行指导。有利于仓库资源使用。

 

Arch (及衍生版Gentoo,Manjaro) 中使用pacman更新的相关命令

在 Arch/ArchBang/Gentoo 中使用的 pacman 更新时如果报错,一般都是gpg签名不可信的问题.

需要选初始化gpg keys. 已经初始化过签名key的, 直接更新就可以了.

  1. 初始化 key:
    pacman-key --init

    验证已存档使用的 keys:

    pacman-key --populate archlinux

     

  2. 软件版本更新:
    pacman -Syy

     

    内核版本更新:

    pacman -Su
    pacman -Suy

     

    缓存中移除所有其他包吗?

    pacman -Syc

使用 .NET Framework 的跨平台开发

(相关参阅)可移植类库 –  http://msdn.microsoft.com/zh-cn/library/gg597391(v=vs.100).aspx

.NET Framework 4.5         

Visual Studio 2012 中的 可移植类库 项目支持 .NET Framework 应用的跨平台开发。

使用此项目编写和生成的可移植程序集,无须在多个平台的修改即可运行,例如 Windows 7,Windows 8,Silverlight ,Windows Phone 和 Xbox 360。             例如,可以创建在桌面应用程序、Windows 应用商店应用程序和移动应用程序中包含共享业务逻辑的类,然后从不同类型的应用程序中引用这些类。

可移植类库项目支持 .NET Framework、Silverlight、适用于 Windows 应用商店应用的 .NET、Windows Phone 和 Xbox 360 中的部分程序集,并提供可用于生成不在这些平台上进行修改也可运行的程序集的 Visual Studio 模板。             如果没有使用可移植类库项目,您必须先指定单个应用程序类型,然后手动修改其他应用程序类型的类库。  可移植类库 项目,可以通过生成在不同设备上的应用程序之间共享的可移植程序集来减少开发和测试代码的时间和费用。

                 说明
如果您使用的是 Visual Studio 2013,则可用的选项和菜单可能与本文中的描述有所不同。

以下各节对 可移植类库 的功能进行了介绍:

  • 先决条件
  • 目标平台
  • 支持的功能
  • 受支持的类型和成员
  • 平台抽象
  • 支持模型-视图-视图模型 (MVVM) 模式
  • 创建可移植类库项目。
  • 选择目标平台
  • 使用可移植类库
先决条件


如果将 Visual Studio 2012 的多平台版本用作开发环境,则您所需的用于开发可移植类库项目的几乎所有内容均可供您使用。               值得注意的是,可移植类库在某些 Visual Studio 单平台版本中不可用,例如 Visual Studio Express for Windows 8。  Windows Phone SDK 8.0 in addition to the version of Visual Studio 2012 that you already have installed.’>此外,如果要面向 Windows Phone 8 进行开发,除了您已经安装的 Visual Studio 2012 版本,还必须安装 Windows Phone SDK 8.0。Portable Library Tools, and save the download file (PortableLibraryTools.exe) on your computer.’>若要在未安装 Visual Studio 2012 的情况下在生成计算机上安装可移植类库工具,请下载 Portable Library Tools (可移植库工具),并将下载的文件 (PortableLibraryTools.exe) 保存到您的计算机上。               /buildmachine switch on the command line.’>从命令提示符窗口运行安装程序,并包括命令行上的 /buildmachine 开关。
目标平台


当您创建 可移植类库 项目时,可以选择要针对的两个或多个平台。               下表显示可用平台。

平台 版本
.NET Framework .NET Framework 4 和更高版本.NET Framework 4.0.3 和更高版本.NET Framework 4.5
Silverlight Silverlight 4 和更高版本(默认选中)。Silverlight 5
Windows Phone Windows Phone 7 和更高版本(默认选中)Windows Phone 7.5 和更高版本Windows Phone 8

                           重要事项
Windows Phone SDK 8.0 for the Windows Phone 8 option. ‘>如果选择 Windows Phone 8,则必须安装 Windows Phone SDK 8.0。
适用于 Windows 应用商店应用的 .NET (*) 不可用
Xbox 360 不可用

该表标识默认情况下处于选中状态的四个平台或版本。               Project Properties dialog box, as shown in the section Selecting the Platforms to Target.’>如 选择要面向的平台 所示,可以通过使用“项目属性”对话框来更改这些默认平台。

支持的功能


在指定目标平台时,在 可移植类库 项目中,仅在您的项目中自动引用这些平台支持的程序集。               您不必添加或移除程序集。  如果您更改目标平台,则自动更新引用的程序集。如果您只以 .NET Framework 4.5 和 适用于 Windows 应用商店应用的 .NET 为目标,那么您就有权访问比其他平台组合中更大的程序集。               此较大程序集的集合与 适用于 Windows 应用商店应用的 .NET 几乎是相同的,但是不包括 Windows.UI.Xaml 命名空间中的类。  .NET for Windows Store apps – supported APIs in the Windows Dev Center.’>有关详细信息,请参见 Windows 开发人员中心中的 .NET for Windows Store apps – supported APIs(用于 Windows 应用商店应用程序的 .NET–受支持的 API)。下表显示了可用平台和版本上支持的功能。

功能 .NET Framework Windows 应用商店 Silverlight Windows Phone Xbox 360
核心
LINQ
IQueryable 7.5 和更高版本
动态关键字 仅限 4.5
Managed Extensibility Framework (MEF)
网络类库 (NCL)
序列化
Windows Communication Foundation (WCF)
模型视图视图模型 (MVVM) 仅限 4.5
数据批注 仅 4.0.3 和 4.5
XLINQ 仅 4.0.3 和 4.5
System.Numerics
受支持的类型和成员


在 可移植类库 项目中可用的类型和成员受若干兼容性因素约束:

  • 它们必须在所选的目标平台之间共享。
  • 必须行为与平台上的这些行为类似。
  • 它们不得是要弃用的候选项。
  • 它们必须在可移植环境中才有意义,特别是在支持成员时是不可移植时。

例如,可移植类库项目不包含任何 UI 相关类型或成员,原因是不同设备的 UI 的行为不同。               如果您的目标是在 可移植类库 引入之前发布的平台(如 Xbox、.NET Framework 4 和Windows Phone 7),那么您可能会遇到限制。

.NET Framework Class Library.’>可查找 可移植类库 支持的成员,在 .NET Framework Class Library(.NET Framework 类库)的参考主题中查找。               在类的成员表中,受支持的成员旁边会显示以下可移植类库图标。

Chars property in the String class is supported in the Portable Class Library.’>例如,下面的图像显示,在 String 类中的 Chars 属性在 可移植类库 中支持。

Version Information section of a reference topic for a note indicating that a type or member is supported in the Portable Class Library project, as shown below.’>按如下显示,还可以查看参考主题的“版本信息”节,了解指示在可移植类库项目中受支持的类型或成员的注释。

平台抽象


通常,您需要从可移植类中调用不可移植的成员。               无法直接调用不可移植的成员,因为这些成员不适用于 可移植类库 项目。  相反,您可以在 可移植类库 项目中创建一个抽象类并可以从所有可移植代码中使用该类。  在特定于平台的项目中,创建抽象类的子类并实现特定于平台的行为。以下示例显示与本地设置一起使用的可移植类。               在 Windows 应用商店 应用程序和 Silverlight 应用程序中处理本地设置的方式各不相同,因此可移植类不提供任何实现详细信息。

C#
using System;

namespace ExamplePortableLibrary
{
    public abstract class ExampleLocalSettings
    {
        public abstract void SetLocalValue(string name, object value);

        public static ExampleLocalSettings Instance { get; set; }
    }
}

在 可移植类库 项目中,可以按以下方式使用。

C#
ExampleLocalSettings.Instance.SetLocalValue("ExampleSetting", "New value to add");

在您的 Silverlight 项目中,添加引用到可移植的程序集,然后创建实现特定于 Silverlight 环境的本地设置操作的子类。  ExampleLocalSettings class.’>下面的示例演示 ExampleLocalSettings 类的 Silverlight 实现。

C#
using System;
using System.IO.IsolatedStorage;
using ExamplePortableLibrary;

namespace SilverlightApplication1
{
    class SilverlightImplementation : ExampleLocalSettings
    {
        public override void SetLocalValue(string name, object value)
        {
            IsolatedStorageSettings.ApplicationSettings.Add(name, value);
        }
    }
}

在您的 Windows 应用商店 应用程序中,添加引用到可移植的程序集,然后创建实现特定于 Windows 应用商店 应用程序的本地设置操作的子类。  ExampleLocalSettings class for a Windows Store app.’>下面的示例演示 Windows 应用商店 应用程序的 ExampleLocalSettings 类的实现。

C#
using System;
using Windows.Storage;
using ExamplePortableLibrary;

namespace App1
{
    class AppImplementation : ExampleLocalSettings
    {
        public override void SetLocalValue(string name, object value)
        {
            ApplicationData.Current.LocalSettings.Values[name] = value;
        }
    }
}

Instance property.’>在 Silverlight 应用程序和 Windows 应用商店 应用程序两个中,必须初始化子类的特定实现并将其设置为 Instance 属性。  通常,您在该应用程序开始时创建此示例。  以下示例显示如何初始化 Silverlight 实现。

C#
ExampleLocalSettings.Instance = new SilverlightImplementation();

以下示例显示如何为 Windows 应用商店 应用程序初始化实现。

C#
ExampleLocalSettings.Instance = new AppImplementation();
支持模型-视图-视图模型 (MVVM) 模式


如果您的目标是 .NET Framework 4.5、适用于 Windows 应用商店应用的 .NET、Silverlight 和 Windows Phone,则可以在解决方案中实现视图 MVVM 模式。               实现此模式的类包括以下:

  • System.Collections.ObjectModel.ObservableCollection<T>
  • System.Collections.ObjectModel.ReadOnlyObservableCollection<T>
  • System.Collections.Specialized.INotifyCollectionChanged
  • System.Collections.Specialized.NotifyCollectionChangedAction
  • System.Collections.Specialized.NotifyCollectionChangedEventArgs
  • System.Collections.Specialized.NotifyCollectionChangedEventHandler
  • System.ComponentModel.DataErrorsChangedEventArgs
  • System.ComponentModel.INotifyDataErrorInfo
  • System.ComponentModel.INotifyPropertyChanged
  • System.Windows.Input.ICommand

Using Portable Class Library with Model-View-View Model.’>有关如何在 可移植类库 项目中实现 MVVM 模式的更多信息,请参见 将可移植类库与模型-视图-视图模型配合使用。

创建可移植类库项目


Portable Class Library template under Visual C# or Visual Basic.’>若要创建 可移植类库 项目,需要在 Visual Studio 2012 中创建一个新项目,然后在 Visual C# 或 Visual Basic 下选择“可移植类库”模板。
选择目标平台


默认情况下,可移植类库项目面向以下平台:

  • .NET Framework 4.5
  • Silverlight 4 及更新版本
  • Windows Phone 7 及更高版本
  • 适用于 Windows 应用商店应用的 .NET

该项目只引用受这些平台支持的程序集。               Solution Explorer, open the shortcut menu for the Portable Class Library project, and then choose Properties.’>若要更改目标平台,则在“解决方案资源管理器”中,打开 可移植类库 项目的快捷菜单,然后选择“属性”。

Library tab specifies the platforms that are currently targeted.’>在项目属性页上,“库”选项卡指定当前面向的平台。

Change button, and then select the appropriate check boxes.’>若要添加或移除目标平台,请选择“更改” 按钮,然后选择相应的复选框。

更改目标平台时,该项目中可用的程序集会发生更改以匹配您所选平台支持的程序集。               如果您的项目引用的程序集不受某个所选平台支持,必须移除对相应程序集的引用或更改目标平台。

使用可移植类库


在您生成 可移植类库 项目后,只是从其他项目引用该项目。               可以引用该项目或包含您要访问的类的特定程序集。若要运行引用 可移植类库 程序集的应用程序,必须在计算机上安装所需版本(或更高版本)的目标平台。               Visual Studio 2012 包含所有必需的架构,因此您可以运行该应用程序,而无需在用于开发应用程序的计算机上进行进一步修改。

部署 .NET Framework 应用程序

部署引用 可移植类库 程序集的 .NET Framework 应用程序时,必须在正确版本的 .NET Framework 上指定一个依赖项。                 通过指定此依赖项,可确保与您的应用程序一起安装所需的版本。  update, Update 4.0.3 for the .NET Framework 4, or the .NET Framework 4.5 installed.’>如果面向的是 .NET Framework 4 或更高版本,则必须已安装含 update(更新)的 .NET Framework 4、.NET Framework 4 的更新 4.0.3 或 .NET Framework 4.5。

  • Solution Explorer, choose the project node for the project you want to publish. (This is the project that references the Portable Class Library project.) On the menu bar, choose Project, Properties, and then choose the Publish tab.’>若要使用 ClickOnce 部署创建依赖项,请在“解决方案资源管理器”中,选择您要发布的项目对应的项目节点。(这是引用可移植类库项目的项目。)在菜单栏上,依次选择“项目”、“属性”,然后选择“发布”选项卡。                     Publish page, choose Prerequisites.’>在“发布”页上,选择“系统必备”。  选择所需 .NET framework 版本(或 .NET framework 4 更新)作为系统必备组件。
  • Solution Explorer, choose the setup project.’>若要创建安装项目的依赖项,请在“解决方案资源管理器”中,选择此安装项目。                     Project, Properties, Prerequisites.’>在菜单栏上,依次选择“项目”、“属性”、“系统必备组件”。  选择所需 .NET Framework 版本作为系统必备组件。

.NET Framework Deployment Guide for Developers.’>有关部署 .NET Framework 应用程序的更多信息,请参见 .NET Framework 部署指南(针对开发人员)。

部署基于 Silverlight 的应用程序

部署引用 可移植类库 程序集的基于 Silverlight 的应用程序时,您必须确保该应用程序所需的最低运行时版本匹配其目标版本。                 如果面向的是 Silverlight 4,则版本必须是 4.0.60129.0 或更高版本。  &lt;param name=”minRuntimeVersion” value=”4.0.60129.0″ /&gt; in the webpage that hosts the Silverlight-based app, as follows:’>通过在承载基于 Silverlight 的应用程序的网页中包括,可设置 <param name=”minRuntimeVersion” value=”4.0.60129.0″ /> 参数值。

XAML
<div id="silverlightControlHost">
    <object data="data:application/x-silverlight-2," 
           type="application/x-silverlight-2" width="100%" height="100%">
    <param name="source" value="ClientBin/SilverlightApplication.xap"/>
    <param name="onError" value="onSilverlightError" />
    <param name="background" value="white" />
    <param name="minRuntimeVersion" value="4.0.60129.0" />
    <param name="autoUpgrade" value="true" />
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" 
             style="text-decoration:none">
      <img src=http://go.microsoft.com/fwlink/?LinkId=161376
             alt="Get Microsoft Silverlight" style="border-style:none"/>
    </a>
  </object>
   <iframe id="_sl_historyFrame" 
              style="visibility:hidden;height:0px;width:0px;border:0px">
   </iframe>
</div>

可移植类库中的 API 差异

为了使可移植类库程序集在所有支持的平台中兼容,稍微更改了可移植类库中的部分成员。                 API Differences in Portable Class Library.’>有关对哪些成员进行了更改以及进行了怎样的更改的详细信息,请参见可移植类库中的 API 差异。

原文连接: http://msdn.microsoft.com/zh-cn/library/gg597391(v=vs.110).aspx#feedback

关于修复WordPress固定链接的改变/迁移 (Change Permalink Migration)

当服务器迁移,需要更换WordPress地址路径时,或是导入了新数据时,会遇到固定链接 改变,文章ID也不正确的情况。

我们需要修正这个问题,以我一些经验为例:

 

例如,我在迁移服务器后,且又多次导入了几个时期分别备份的数据后:

(原URL):http://bohu.net/wp/2006/07/197,orz-and-wtf/  变成了 (新URL)http://bohu.net/blog/197

原文件夹是 wp 新文件夹为 blog

 

设置转发(Redirect)

那么首先设置web服务器的重定向类型(Redirect Type),一般web服务器都支持一下3种Redirect:
301 – Permanent(永久)
302 – Temporary(临时)
303 – Replaced (替换)
详细参数说明,查看 维基百科 HTTP状态码 :3xx重定向
用   303 ,  Replaced  redirected (303)  重定向 wp 到 blog,
Local URL Path Type Redirect URL
/wp 303 http://bohu.net/blog

 

303 – Replaced 顾名思义,就是可以替换URL中的地址,而且正确的响应所传递的参数。? 号之后的参数不会丢失。

如: http://bohu.net/blog/post.php?post=1234&action=edit  303 替换为 http://bohu.net/wp/post.php?post=1234&action=edit

这样设置之后 访问 bohu.net/wp 就可以 转到 bohu.net/blog 了。

 

手动修复ID

但是元文章ID是197, 现在变为了2553,你如果用插件修复固定连接的话那么,可以忽略这一部分。

我尝试手动修复了ID。先下载插件 ”ShowID

下载插件:ShowID for Post/Page/Category/Tag/Comment – http://ounziw.com/2010/02/05/showid/

启用之后就可以在文章列表看到每篇文章的 ID 了。我没找到自动更改ID的插件,进数据库自己修改的。

这样 http://bohu.net/blog/197 就可以恢复访问到了。

 

修复固定链接改变/迁移

但是之前的固定连接 ”197,orz-and-wtf“ 为两个参数组合的,所以原URL还不能直接访问。

需要使用插件转发到新固定连接,我最先用的是 ”Advanced Permalinks“

下载插件:Advanced Permalinks – http://urbangiraffe.com/plugins/advanced-permalinks/

可以完成转发效果,不过发现设置有点不太简单化,而且我的翻页有问题。

下面是附带解决固定连接修改后翻页的问题。

翻页有问题     有时候翻到第二页或其他页不能正常工作,地址如下:
 http://www.example.com/page/2/  http://www.example.name/category/categoryname/page/2/  http://www.example/year/month/day/page/2/  http://www.example/year/month/page/2/
    访问上面的任何一个链接,出现提示说: “Sorry, no posts match that criteria.”
    这是.htaccess造成的,删掉,重新生成就好了。

看到”Advanced Permalinks“已经是2年未更新了,最后还是更换了插件为 ”Permalink Finder“。

下载插件:Permalink Finder –  http://www.blogseye.com/

启用”Permalink Finder“Permalink-Finder Options”菜单,我按照默认设置。

这样就自动化完成修复固定链接的改变/迁移了。设置基本上不需要多少的改变。