(一)编程思想
1. 静态编译型语言 : Java、C#
优点:适合企业级复杂项目;适合维护、迭代项目;可维护代码
缺点:笨重
2. 动态语言:Python 、PHP、JavaScript
优点:灵活
大项目难以维护
3.软件工程:
目的:开发、维护、迭代项目
开闭原则 Open Closed Principle(OCP):扩展开放,修改封闭。新增业务模块/类;不修改原来的模块/类。
4.面向抽象编程 :
解决的问题:编程最终目的是调用方法,而不是实例化类。面向具体的类编程,一旦该类发生修改,所有引用该类的地方都必须随之修改。
目的:实现可维护的代码
实现方式:① Interface;
② 设计模式 ;
③ IOC 、DI。
5.面向对象:实例化对象,调用方法(完成业务逻辑)
(二)编程方式的演进(正向思维---主动去获取对象)
1. 普通方式:用户的输入不同--->创建的对象不同(用户只能输入对象名称,程序负责将名称转化为对应的对象)。
存在的问题:频繁变更,会造成bug。 变化------导致不稳定。
1 public class Camille { 2 3 public void q(){ 4 System.out.println("Camille Q"); 5 } 6 7 public void w(){ 8 System.out.println("Camille W"); 9 } 10 11 12 public void e(){ 13 System.out.println("Camille E"); 14 } 15 16 public void r(){ 17 System.out.println("Camille R"); 18 } 19 20 } 21 22 public class Diana { 23 24 /** 25 * 技能q 26 */ 27 public void q(){ 28 System.out.println("Diana Q"); 29 } 30 31 /** 32 * 技能w 33 */ 34 public void w(){ 35 System.out.println("Diana W"); 36 } 37 38 /** 39 * 技能e 40 */ 41 public void e(){ 42 System.out.println("Diana E"); 43 } 44 45 /** 46 * 技能r 47 */ 48 public void r(){ 49 System.out.println("Diana R"); 50 } 51 52 } 53 54 public class Irelia { 55 56 /** 57 * 技能q 58 */ 59 public void q(){ 60 System.out.println("Irelia Q"); 61 } 62 63 /** 64 * 技能w 65 */ 66 public void w(){ 67 System.out.println("Irelia W"); 68 } 69 70 /** 71 * 技能e 72 */ 73 public void e(){ 74 System.out.println("Irelia E"); 75 } 76 77 /** 78 * 技能r 79 */ 80 public void r(){ 81 System.out.println("Irelia R"); 82 } 83 84 } 85 86 87 private static void v1(String name) { 88 //尽可能保证主体代码稳定性 89 //存在的问题:频繁变更,会造成bug 90 switch (name) { 91 case "Diana": 92 Diana diana = new Diana(); 93 diana.e(); 94 break; 95 case "Irelia": 96 Irelia irelia = new Irelia(); 97 irelia.e(); 98 break; 99 case "Camille": 100 Camille camille = new Camille(); 101 camille.e(); 102 break; 103 } 104 }
2. Interface:统一方法的调用,但不能统一对象的实例化。
1 public interface Skill { 2 3 void q(); 4 5 void w(); 6 7 void e(); 8 9 void r(); 10 } 11 12 13 public class CamilleImpl implements Skill { 14 15 @Override 16 public void q(){ 17 System.out.println("Camille Q"); 18 } 19 20 @Override 21 public void w(){ 22 System.out.println("Camille W"); 23 } 24 25 @Override 26 public void e(){ 27 System.out.println("Camille E"); 28 } 29 30 @Override 31 public void r(){ 32 System.out.println("Camille R"); 33 } 34 35 } 36 37 public class DianaImpl implements Skill { 38 39 /** 40 * 技能q 41 */ 42 @Override 43 public void q(){ 44 System.out.println("Diana Q"); 45 } 46 47 /** 48 * 技能w 49 */ 50 @Override 51 public void w(){ 52 System.out.println("Diana W"); 53 } 54 55 /** 56 * 技能e 57 */ 58 @Override 59 public void e(){ 60 System.out.println("Diana E"); 61 } 62 63 /** 64 * 技能r 65 */ 66 @Override 67 public void r(){ 68 System.out.println("Diana R"); 69 } 70 71 } 72 73 74 public class IreliaImpl implements Skill { 75 76 /** 77 * 技能q 78 */ 79 @Override 80 public void q(){ 81 System.out.println("Irelia Q"); 82 } 83 84 /** 85 * 技能w 86 */ 87 @Override 88 public void w(){ 89 System.out.println("Irelia W"); 90 } 91 92 /** 93 * 技能e 94 */ 95 @Override 96 public void e(){ 97 System.out.println("Irelia E"); 98 } 99 100 /** 101 * 技能r 102 */ 103 @Override 104 public void r(){ 105 System.out.println("Irelia R"); 106 } 107 108 } 109 110 111 private static void v2(String name) throws Exception { 112 113 Skill skill; 114 //无法解决对象的统一实例化 115 switch (name) { 116 case "Diana": 117 skill = new DianaImpl(); 118 break; 119 case "Irelia": 120 skill = new IreliaImpl(); 121 break; 122 case "Camille": 123 skill = new CamilleImpl(); 124 break; 125 default: 126 throw new Exception(); 127 } 128 //解决了方法的统一调用 129 skill.e(); 130 }
3. 设计模式:把对象的实例化的过程,转移到其他代码片段里 (工厂模式)
1 public class HeroFactory { 2 3 //稳定性具有相对性 :代码中总会存在不稳定,隔离这些不稳定的,保证其它部分代码的稳定性。 4 //把变化隔离和封装起来 5 6 //转移了对象实例化的位置 7 //存在不稳定性:用户的输入不同---创建的对象不同(用户只能输入对象名称,程序负责将名称转化为对应的对象) 8 //solution : 用户直接输入对象 ---- 反射 9 public static Skill getHero(String name) throws Exception{ 10 Skill skill; 11 12 switch (name) { 13 case "Diana": 14 skill = new DianaImpl(); 15 break; 16 case "Irelia": 17 skill = new IreliaImpl(); 18 break; 19 case "Camille": 20 skill = new CamilleImpl(); 21 break; 22 default: 23 throw new Exception(); 24 } 25 26 return skill; 27 28 } 29 30 } 31 32 33 /** 34 * v3()实现了OCP,但是HeroFactory没有实现OCP 35 * 保持了一段代码的稳定性,将风险转接到另一段代码里。 36 * 若getHero()不是静态方法,则v3()依然无法避免HeroFactory 对象的实例化 37 * @param name 38 * @throws Exception 39 */ 40 private static void v3(String name) throws Exception { 41 //抽象工厂模式 解决 HeroFactory的不稳定问题 42 //Spring IOC : ApplicationContext ------>抽象工厂模式 : 对象的实例化 43 v3.Skill skill = HeroFactory.getHero(name); 44 skill.e(); 45 46 }
4. 反射:动态创建对象,通过反射消除所有的变化。
当业务或者用户的输入有变化时,我们必须创建不同的对象响应用户的输入。
解决方法 : 用户直接输入对象,动态创建对象,通过反射消除所有的变化。
1 public class Reflective { 2 3 public static Skill getHero(String name) throws Exception{ 4 5 Skill skill; 6 7 //元类 8 //包名+类名 9 10 //缺点:反射性能低 11 12 //正向思维 13 String className = "v4.impl." + name; 14 Class<?> clazz = Class.forName(className); 15 Object object = clazz.getDeclaredConstructor().newInstance(); 16 skill = (Skill)object; 17 18 return skill; 19 } 20 21 } 22 23 24 private static void v4(String name) throws Exception { 25 26 v4.Skill skill = Reflective.getHero(name); 27 skill.e(); 28 } 29 30 31 private static String getPlayerChoice(){ 32 System.out.println("Please enter a hero's name:"); 33 Scanner scanner = new Scanner(System.in); 34 String name = scanner.nextLine(); 35 return name; 36 37 } 38 39 40 public static void main(String[] args) throws Exception{ 41 String name = getPlayerChoice(); 42 43 // v1(name); 44 // v2(name); 45 // v3(name); 46 v4(name); 47 }
5.Spring IOC(逆向思维---容器直接给予对象):
稳定性具有相对性 :代码中总会存在不稳定,隔离这些不稳定的,保证其它部分代码的稳定性。(把变化隔离和封装起来)
(二)Spring
1. IOC :控制反转。容器作为主控方,解决实例化类 的问题(即new Object())。
2. DI (Dependency Injection ):依赖注入
容器注入对象的实例。
形式:①属性注入;
②构造注入;
③接口注入。
3. DIP (Dependency Inversion Principle ):依赖倒置
高层模块(抽象)不应该依赖低层模块,两者都应该依赖抽象。
抽象不应该依赖细节,细节应该依赖抽象。