Java私塾程序设计设计模式理论笔记经典.docx
《Java私塾程序设计设计模式理论笔记经典.docx》由会员分享,可在线阅读,更多相关《Java私塾程序设计设计模式理论笔记经典.docx(32页珍藏版)》请在冰豆网上搜索。
Java私塾程序设计设计模式理论笔记经典
Java私塾Java高级-设计模式等理论
举例:
优势只希望内存中只有一个实例,无论多少用户请求,只有一个实例,这就是用到了static修饰的类方法
方式一:
packagecom.test;
publicclassA{
//5.用来保存自己的类实例
//6.返回的实例是static
privatestaticAa=null;
//1.收回外部能够newA()的权限
privateA(){
}
//2.主动给外部调用提供自己的实例
//3.必须返回static类型的,才能唯一
publicstaticAgetInstance(){
//4.控制构造方法调用的次数:
只在第一次调用时才new实例
if(a==null){
a=newA();
}
returna;
}
}
方式二:
packagecom.test;
publicclassA{
//5.用来保存自己的类实例,直接new
privatestaticAa=newA();
//1.收回外部能够newA()的权限
privateA(){
}
//2.主动给外部调用提供自己的实例
publicstaticAgetInstance(){
returna;
}
}
思考:
思考:
(1)这两种解决方案有什么优缺点?
答:
方案一在刚装载不需实例化,节省内存空间,但每次调用都要判断if(a==null),消耗时间;
线程不安全,在并发访问时,可能new多个(实际只用一个,其余的实例成了垃圾),可以
使用同步处理Synchronized;
延迟加载(调用时才实例化),
缓存(使用了缓存机制)
方案二在刚初始化时,就产生了实习,占用内存空间,但不用判断,节省时间;
线程安全。
缓存(使用了缓存机制)
1
11111
(2)这两种解决方案如何选择?
答:
应根据实际情况选择,一般使用方案一(理由:
时间可以推迟,但内存空间有限)
(一)单例模式
缓存写法举例:
java中最常用的缓存是集合,如Map
packagecom.test;
importjava.util.HashMap;
importjava.util.Map;
publicclassA{
//1.定义一个用来缓存数据的的容器集合Map
privatestaticMapmap=newHashMap();
publicstaticAgetInstance(){
//到缓存容器map中查找需要的数据
Aa=(A)map.get("a");
//如果找不到,就new一个或者从数据库获取,再将它放到map中
if(a==null){
a=newA();
map.put("a",a);
}
//找到了直接使用
returna;
}
}
控制实例当然数量:
(2)工厂模式
思想:
java是面向几口编程:
java只知道接口名,不用知道集体的实现类是哪个
举例:
(1)定义接口StudentDao
packagecom.test.factroy;
//定义接口
publicinterfaceStudentDao{
publicStringshow();
}
(2)实现接口
packagecom.test.factroy;
publicclassStudentDaoImplimplementsStudentDao{
//实现接口
publicStringshow(){
//TODO自动生成方法存根
System.out.println("StudentDaoImpl---->Hello!
");
return"hello";
}
}
(3)定义工厂
packagecom.test.factroy;
publicclassStudentFactroy{
//工厂类使用的静态方法,直接返回接口的实现类实例,一般返回的是接口(上转型)
publicstaticStudentDaocreateStudentDao()
{
//工厂角色:
选择实现的类实例,根据条件
returnnewStudentDaoImpl();
}
//另外,工程不仅可以返回接口,实现类实例,也可以返回任何想要使用的类型
//一般返回接口
}
(4)测试使用
packagecom.factory.test;
importcom.test.factroy.StudentDao;
importcom.test.factroy.StudentFactroy;
publicclassFactoryTest{
publicstaticvoidmain(Strings[])
{
//调用工厂,返回的是接口实现类的实例,上转型到接口
//java是面向几口编程:
java只知道接口名,不用知道集体的实现类是哪个。
StudentDaostudentDao=StudentFactroy.createStudentDao();
System.out.println(studentDao.show());
}
}
思考:
因为java是面向几口编程:
java只知道接口名,不用知道集体的实现类是哪个。
如果一个接
口有多个实现类,如何正确的使用哪个实现类的实例?
---答:
工厂类的主要职责是:
选择实现类的实例(接口)
因此,应该在工厂类中根据条件选择实例
例如:
工厂
packagecom.test.factroy;
publicclassStudentFactroy{
//也可做成单例工厂static
publicstaticStudentDaocreateStudentDao(inttype)
{
//工厂角色:
选择实现的类实例,根据条件
if(type==1)
{
returnnewStudentDaoImpl();
}
if(type==2)
{
returnnewStudentDaoImpl2();
}
returnnull;
}
}
测试:
packagecom.factory.test;
importcom.test.factroy.StudentDao;
importcom.test.factroy.StudentFactroy;
publicclassFactoryTest{
publicstaticvoidmain(Strings[])
{
//调用工厂,返回的是接口实现类的实例,上转型到接口
//java是面向几口编程:
java只知道接口名,不用知道集体的实现类是哪个。
StudentDaostudentDao=StudentFactroy.createStudentDao
(2);
System.out.println(studentDao.show());
}
}
(3)设计模式:
值对象
即:
普通的存储属性值的javabean
命名规则,如值对象User
可以命名为:
UserVO.java,UserValueObject.java,UserModel.java
例子:
UserVO.java
packagecom.test.vo;
importjava.sql.Date;
//1.推荐实现序列化(用在分布式系统要序列化),非必须
//publicclassUserVOimplementsSerializable
publicclassUserVO{
//2.定义私有属性;3.实现set,get方法;4.重写equals方法和toString方法(非必须)
privateDatebirthday;
privateintid;
privatebooleanmarry;
privateStringname;
publicDategetBirthday(){
returnbirthday;
}
publicintgetId(){
returnid;
}
publicStringgetName(){
returnname;
}
publicbooleanisMarry(){
returnmarry;
}
publicvoidsetBirthday(Datebirthday){
this.birthday=birthday;
}
publicvoidsetId(intid){
this.id=id;
}
publicvoidsetMarry(booleanmarry){
this.marry=marry;
}
publicvoidsetName(Stringname){
this.name=name;
}
}
思考:
看似值对象很简单,不过可以变形使用:
例如:
可以只有get方法,防止属性被修改,可以在get方法中修改成自己的处理值。
等等。
(4)DAO设计模式
例子类似工厂模式(略)
思考:
客户端程序只关心要去做什么(如:
增删改查),不关心如何实现(如:
不同的数据源,不同的存储类型,不同的数据库供应商,不同的访问方式,一接口不同的实现)
-------通过DAO封装一个接口,此接口有不同的实现方式,如:
A机器,B机器使用不同的实现类实现接口;
Oracle数据库,Sqlserver数据库,mysql数据库使用不同的类实现接口;
File文件,xml文件,关系数据库存储类型不同,有不同的实现接口类;
调用时,根据条件(参数)调用工厂,选择相应的实现类实例。