• 1. 突破论程序员的自我修养 叶军 http://www.yejun.cnUED Team Design
  • 2. 大纲向前看:程序员升职记 倒过来:程序员的七种武器 常回头:程序员的想说写
  • 3. 程序员升职记技术?能力?学历?态度?
  • 4. 例子淘宝的同学 我们身边的人
  • 5. 程序员升职记老板对下属的普遍性评价原则
  • 6. 程序员升职记沟通
  • 7. 程序员的七种武器数组、字符、HASH、QUEUE、MAP 正则表达式 SQL 调试 数据源 StarUML 、图表达设计思想 专属的武器:兴趣
  • 8. 数据结构数据结构有什么用? 产品DETAIL的结构 物流运费的信息 COUPON的信息 NAPOLI的消息 CACHE的集群
  • 9. 正则如何在vi中查找替换一个字符串? http://deerchao.net/tutorials/regex/regex.htm http://en.wikipedia.org/wiki/Kleene_star DFA NFA
  • 10. SQL存过 优化 索引 磁盘IO 例:500万产品,持久化选型
  • 11. 调试你懂的
  • 12. 数据源MAP-REDUCEStorageK-VSQLIndexWeb Server监控
  • 13. 类图
  • 14. 图表达设计流程图
  • 15. 部署图
  • 16. 策略(Strategy)模式从一个设计模式看设计思路的形成 程序员要有设计,而不只是CODING
  • 17. 例一套模拟鸭子游戏:SimUDuck。游戏中出现各种Duck,鸭子会游泳(swim) ,也会叫(quack)。
  • 18. (本页无文本内容)
  • 19. 需求总是变化的现在得让鸭子能飞
  • 20. 一种自然的想法只需要在Duck类中加上fly()方法,所有Duck就都会继承fly()。
  • 21. 会飞的「橡皮鸭」不好的后果:并非Duck的所有子类都会飞。在Duck超类中加上新的行为, 这会使得某些子类也具有这个不恰当的行为。 「橡皮鸭」不具有飞的能力,但基类强制它继承了这个行为。
  • 22. 教训在超类中加上一个行为,就会导致所有的子类都强制具备该行为,连那些不该具备的子类也无法免除。 进一步 :对代码所做的局部修改,影响层面可能不只局部。 进一步 :当涉及到扩展时,为了复用代码目的而使用继承并不总是合适的。
  • 23. 改善可以把橡皮鸭类中的fly()方法覆盖掉,就好像覆盖quack()的作法一样: class RubberDuck : Duck { quack() { 吱吱叫} display() { 橡皮鸭 } fly() { 覆盖,什么事都不做 } }
  • 24. 不足如果以后加入不会飞也不会叫的诱饵鸭,则同样需要覆盖不适合自己的方法。
  • 25. 问题利用继承来提供Duck的行为,这会导致哪些缺点?
  • 26. 继承並非答案每当有新的鸭子子类出现,就要被迫检查并可能需要覆盖fly()和quack()。
  • 27. 利用接口把fly()取出,放进Flyable接口中。只对会飞的子类才继承并实现此接口。 同样, 设计Quackable接口,只对会叫的子类才继承此接口。
  • 28. 利用接口
  • 29. 问题重复的代码会变多 -- 对不支持基类中有实现的多继承的语言。 代码无法复用。相同的实现分布在多个子类。 C++中多继承的问题。
  • 30. 继承并不是适当的解决方式 单继承:并非所有的子类都具有Fly和Quack的行为。 多继承:继承在解决问题的同时造成代码无法复用。 单/多继承:具有Fly属性的子类,飞行的动作可能还有多种变化。 多继承:Java等的接口不具有实现代码, 继承接口无法达到代码的复用。 我们希望的目标 当需要改变软件时,可以在对既有的代码影响最小的情况下,轻易达到花较少时间重做代码,而多让程序去做它本身的事。
  • 31. 设计原则:封装变化找出应用中可能需要变化之处,把它们单独封装起来,与不需要变化的代码隔离开。 这个原则并不仅仅是针对类而言。 几乎每个设计模式模式都体现了「系统中的某部分改变不会影响其他部分」。
  • 32. 把会变化的部分取出并封装起来,以便以后可以轻易地扩充此部分,而不影响不需要变化的其他部分。 几乎是每个设计模式背后的精神所在。所有的模式都提供了一套方法让「系统中的某部分改变不会影响其他部分」。 架构、模块、代码。。。
  • 33. 分开变化和不会变化的部分第一步:识别变化:fly()和quack()会随着Duck类的不同而改变。(反过来不成立) 原则 :把逻辑和功能分开。 第二步:把变化的行为从Duck类中分开。 第三步:对取出的fly和quack行为分别建立一组新类。
  • 34. 比较两种分离多态:基类与子类分离:基类负责声明,(不同的)子类完成(不同的)实现。基类不必关心子类的实现。 聚合:逻辑模块与实现模块的分离: 从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为的实现。这样,鸭子类就不再需要知道行为的实现细节。 思考:哪种分离更彻底。
  • 35. 进一步我们的目标:希望一切能有弹性。 思考:运行时动态改变行为: 红头鸭+飞;红头鸭+叫;红头鸭+飞+叫;绿头鸭+飞;绿头鸭+叫;绿头鸭+飞+叫;… 鸭子行为没有弹性 -> 分离出行为 让鸭子的行为可以动态地改 -> 比如在「运行时」动态地「改变」某类DUCK的飞行行为。
  • 36. 设计原则:针对接口编程, 而不是针对实现编程。针对实现:行为是继承超类的具体实现而来,或是继承某个接口并由子类自行实现而来。 缺点:依赖于「实现」,被实现绑死, 很难更改行为 多态 面向对象的重要支撑。 我们不知道实际的子类型是「什么」。我们只关心它知道如何正确地进行 makeSound()的动作就够了。
  • 37. 「飞」接口 和 [叫]接口
  • 38. 现在的结构可以让飞和叫的动作被其他的对象复用,这些行为已经与鸭子类无关。--分离 新增一些行为时,不会影响到既有的行为类。也不会影响使用到飞行行为的鸭子类。 -- 接口不变 + 接口隐藏实现
  • 39. 考虑是不是一定要先把系统做出来,再看看有哪些地方需要变化,然后才回头去把这些地方分离&封装? 大的结构要好,小的可以先放过 不过分前瞻 + 重构 Duck是不是也该设计成一个接口? 要看具体的情况:不要失去继承的原始好处(代码复用)。 可以将基类从接口派生。
  • 40. 考虑常见的类应该代表某种「东西」,同时具备状态与行为。此处用一个类代表一个行为? 一般状态指成员变量, 行为指方法。 其实是逻辑类和功能/实体类的概念。而且我们鼓励把逻辑类和功能类分开。--功能类可以复用;逻辑类更清晰。 逻辑类中又有逻辑和功能;功能类中又功能与 逻辑。 实现「飞」的功能时,需要有高度、速度等变量做逻辑控制,但「飞」对于外界来说它是功能模块。
  • 41. 思考在我们的新设计中, 如果要在系统中加上一个动力的飞行动作,应该怎么做?
  • 42. 答案建立一个FlyRocketPowered类,实现Fly Behavior接口。
  • 43. 鸭子类与行为类的绑定在Duck类中加入飞和叫的接口变量;删除所有Duck(子)类中有关飞和叫的方法,用performFly()和performQuack()取代fly与quack。
  • 44. 还有遗憾,但是…对绿头鸭: quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); 缺点:始化实例变量的作法不够弹性。 好在我们是针对接口编程的,可以通过一些手段方便地运行时动态地改变具体行为的指向。
  • 45. 部分代码public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck() {} public abstract void display(); public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { System.out.println(“All ducks float, even decoys!”); } }
  • 46. 思考如何实现鸭子,好让其行为可以在运行时改变。
  • 47. 解决:动态设定行为自然的想法:增加一个设定方法(sett ermethod)设定鸭子的行为,而不是在鸭子的构造器内实例化。
  • 48. 为模型鸭ModelDuck增加动力的飞行行为: Duck model = new ModelDuck(); model.performFly(); model.setFlyBehavior(new FlyRocketPowered()); model.performFly();
  • 49. 输出结果 1)I can’t fly 2)I’m flying with a rocket! 当调用继承来的setter方法,把动力飞行的行为设定到模型鸭中。 Great! 模型鸭突然具有火箭动力飞行能力。 以后我们可以随时调用这两个方法改变鸭子的飞和叫的行为。
  • 50. 整体的格局
  • 51. 整个重新设计后的类结构,有我们期望的一切,而且分布合理: 的基类Duck实现swim。 的子类实现display。 飞行行为实现FlyBehavior接口。 叫行为实现QuackBehavior接口。
  • 52. 抽象和一般化把行为想成是「一族算法」。在SimUDuck的设计中,算法代表能做的事(不同的叫法和飞行法),可以换成其它任意的算法。 再次注意逻辑类和工具类:工具类总是容易替换的。逻辑类却与具体的案例有关。 另一个理解的角度:抽象的部分与实现的部分。我们努力把抽象的部分与实现的部分分开。 配合其它的模式,可以可以设计出更复杂、更灵活的运用。
  • 53. 概念图:好友网络→消息网络度分布 最短路径分布 聚类系数分布 社区化结构 其它统计特性
  • 54. 常回头想、说、写 博客 内部邮件 内部论坛 内部会议 外部会议 外部组织 打破惯性
  • 55. 实践出真知勇于担当, 大胆尝试, 小心求证,
  • 56. 兴趣最强武器 每个人都有自已的特长 The Blind side