作用:在Think in java 系列书籍以及网上大量的文章都写了其各种各样的好处,我认为言过其实,我们用静态工厂方法,主要原因在于可以根据逻辑需求返回实例对象。可以方便实现工厂模式、单例模式。其它如,有语义方法名、返回其返回类型的任何子类型的对象,方便创建参数化类型实例等等都是无关痛痒的东西。
实现:
将创建实例封装在一个工厂类的静态方法中,静态方法不同的参数返回不同的实例。
示例:
如下所示,电脑工厂类,通过提供静态方法getComputer(String Brand)生产不同品牌的电脑(返回Computer实例对象),客户端只需要调用静态工厂方法传入不同参数即可获得目标对象。
package staticfactory; public interface Computer { public abstract void cal(); }
package staticfactory; public class Mac implements Computer { @Overrid public void cal() { System.out.println("苹果电脑启动。。。。"); } }
package staticfactory; public class HP implements Computer { @Override public void cal() { System.out.println("惠普电脑启动。。。。"); } }
package staticfactory; public class ComputerFactory { public static Computer getComputer(String computerBrand) { switch (computerBrand) { case "Mac": return new Mac(); case "HP": return new HP(); default: return null; } } }
package staticfactory; public class Client { public static void main(String[] args) { Computer computer = ComputerFactory.getComputer("Mac"); Computer computer2 = ComputerFactory.getComputer("HP"); computer.cal(); computer2.cal(); } }
运行结果:
苹果电脑启动。。。。 惠普电脑启动。。。。
一.开闭原则
实现方式:
1. 遵循“抽象约束、封装变化”原则,通过接口或者抽象类为实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。
2.参数类型、引用对象尽量使用接口或者抽象类,而不是实现类。
3.缩小功能颗粒度。功能粒度越小,被复用的可能性就越大,重复利用可能性就越高。
二. 里氏替换原则
简单地说,把父类都替换成它的子类,程序的行为没有变化。只要出现父类的地方,均可用子类替换,而且对整体实现并没有任何影响,提高代码的复用性。
实现方式:
子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。
三. 依赖倒置原则
——高层模块不应该依赖低层模块,两者都应该依赖其抽象
——抽象不应该依赖细节
——细节应该依赖抽象
实现方式:
1.每个类尽量提供接口或抽象类,或者两者都具备。
2.变量的声明类型尽量是接口或者是抽象,模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。
3.任何类都不应该从具体类派生。
4.尽量不要重写基类已经写好的方法(符合里氏替换原则)。
设计模式实质上并没有新的东西,只是一种思想体现,来来去去都是在围绕继承、多态、静态之间做文章。很多人学设计模式很吃力,被其中类之间复杂的引用关系绕晕,我认为掌握设计模式最重要的一步就是把常见类之间关系梳理出来,而UML早已经帮我们做了,拿来理顺即可。
一. 依赖关系Dependency
依赖关系是一种临时关系、使用的弱关系,是耦合度最低的一种关系。
代码表现:一个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)。下例中,猎人(Hunter)和枪(Gun)之间是一种使用关系,猎人使用枪进行射击,枪Gun作为一个参数出现在猎人shoot方法中(Hunter类中猎杀动作shoot()调用了Gun实例的开火fire()方法):
package com.mosang.umlmodule; public class Hunter { private String name; public void shoot(Gun g) { g.fire(); } }
package com.mosang.umlmodule; public class Gun { private String brand; public void fire() { System.out.println("shoot....."); } }
package com.mosang.umlmodule; public class Client { public static void main(String[] args) { Hunter hunter = new Hunter(); hunter.shoot(new Gun()); } }
UML图示:
二. 关联关系Association
关联关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,如学生与老师、公司与员工、宠物与主人等等,存在一对一,一对多,多对多等关系。
代码表现:一个类的对象作为另一个类的成员变量。下例中学生与老师是一种多对多的关系(一个学生同时有多个老师教,一个老师也同时教多个学生),Student类作为成员变量出现在Teacher类中,Teacher类也作为成员变量出现在Student类中:
package com.mosang.umlmodule; import java.util.List; public class Student { private String name; private List<Teacher> teachers; public void study() { } }
package com.mosang.umlmodule; import java.util.List; public class Teacher { private String name; private List<Student> students; public void teach() { } }
UML图示:
【双向的关联可以用带两个箭头或者没有箭头的实线来表示,单向的关联用带一个箭头的实线来表示,箭头从使用类指向被关联的类。也可以在关联线的两端标注角色名,代表两种不同的角色。】 (更多…)
java中,静态方法属于类,直接使用”类名.静态方法”方式访问,也可以通过”实例.方法”访问,后者一般不推荐,但是也是合法的:
package com.mosang.staticInheri; public class Fu { public String a="fu"; public void ordinaryMethod() { System.out.println("Fu ordinaryMethod"); } public static void staticMethod() { System.out.println("Fu static method"); } }
package com.mosang.staticInheri; public class Demo { public static void main(String[] args) { Fu f=new Fu(); f.staticMethod();//使用实例方式访问 Fu.staticMethod();//使用类名直接访问 } }
输出如下:
Fu static method Fu static method
需要注意的是,在存在静态方法情况下的继承,静态方法不能被子类覆盖,即使子类有与父类相同的静态方法(同覆盖规则),也不是覆盖重写,如有Zi类继承如下:
package com.mosang.staticInheri; public class Zi extends Fu{ public String a="zi"; public void ordinaryMethod() { System.out.println("Zi ordinaryMethod"); //实例方法,覆盖重写 } public static void staticMethod() { System.out.println("Zi static method"); //与父类相同的静态方法(方法名、返回值、参数均相同) } }
通过两种方式创建子类实例:
package com.mosang.staticInheri; public class Demo { public static void main(String[] args) { Fu f1=new Zi();//多态方式创建对象 Zi f2=new Zi();//普通方式创建对象 f1.ordinaryMethod(); //输出Zi ordinaryMethod f1.staticMethod();//输出Fu static method f2.ordinaryMethod();//Zi ordinaryMethod f2.staticMethod();//Zi static method } }
输出结果
Zi ordinaryMethod Fu static method Zi ordinaryMethod Zi static method
从上输出结果可看到,父类的静态方法并不能被覆盖,只是被隐藏。
同样,静态成员变量也是一样的道理。出现相同静态字段时父类字段不会将子类字段覆盖,而只是将其“隐藏”。
大学时,学校有个名家讲坛,有很多名人来演讲,包括袁隆平、王石、白岩松、唐骏、王蒙、余秋雨、陈鲁豫,俞敏洪、李开复。。。等等,其中特别多的是央视名嘴,和很多懵懂的大学新生一样,我很热衷于听这样的讲座,想着从中吸取到这些成功人士的思想智慧。然而,更多留下的印象是他们在讲那些所谓光辉往事,多年后想起来,这些花去了大量时间的名人讲座对我毫无帮助,大脑中对这些讲座的印象已经趋近于零,有很多后来还因为人设的坍塌而起了反效果。相反,有一堂看似不起眼的财务管理会计实操课,对我印象深刻。那次老师邀请了一家证券公司的专业财税人员来给我们讲解,讲课人干净利落的职业着装,口齿清晰的表达,逻辑清晰且优美的PPT,娴熟的软件操作,给我留下了极深的印象,第一次觉得财务课程还可以不沉闷,还可以有如此专业深度,这么多年过去,那次课我依然记忆犹新。
我们常常在网上、在节目访谈中,在演讲上,在他人写的书中,看到或听到各种诗般的旅行体验,传奇的创业故事,艰苦奋斗的历程,力挽狂澜的励志片段、远见卓识的前瞻思维、开山劈地般的气魄,这些让你的神经猛然得到刺激,鸡汤效应让人一时间兴奋起来。然而当你走近或去经历的时候,才发现所有这些,都与你想的相去甚远。几乎每个给别人讲故事的人,都不由自主地往其中添加了或多或少的兴奋剂,有的甚至只剩下兴奋剂了。 (更多…)