----------------------- 中关村黑马程序员----------------------
java的饿汉,懒汉,装饰设计模式
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一.面向对象思想几大设计原则:
1.单一职责原则
2.开闭原则
3.里氏替换原则
4.依赖注入原则
5.接口分离原则
6.迪米特原则
所有的设计原则都是为了提高程序软件的 维护性 扩展性 复用性
二.设计模式的分类
一.创建型模式 : 即创建对象
创建型模式:简单工厂模式(讲),工厂方法模式(讲),抽象工厂模式,建造者模式,原型模式,单例模式(重)。(6个)
二.结构型模式:对象的组成(结构)部件
结构型模式:外观模式、适配器模式、代理模式、装饰模式(重)、桥接模式、组合模式、享元模式。(7个)
三.行为型模式 :对象的行为/功能方法
行为型模式:模版方法模式、观察者模式、状态模式、职责链模式、命令模式、访问者模式、策略模式、备忘录模式、迭代器模式(重)、解释器模式。(10个)
四.单例设计模式 --饿汉模式:
A. 确保类在内存中只有一个对象,该实例对象必须自动创建,并且对外提供访问方法,返回这个对象。
(单: 别人不能造对象, 对象只能我造,造一个,提供给别人用,)
B. 如何 确保 类在内存中只有一个对象 ?
1.把类的构造方法私有化,外界就不能造对象了
private Student(){}
2. 成员位置上,自己创建一个类的对象并私化, 外界不能修改 对象的原有值
2.1 让该对象静态化。 静态 方法只能访问静态成员变量(静态对象)
private static Student s = new Student();
3. 定义一个公共的静态化方法对外提供访问( 外界可直接类名调用访问此公共方法,可获取这个对象,)
public static Student getStudent(){ return s;}
C. 如何体现出:饿汉式 : 类一加载运行就创建了对象。
// 静态成员变量(对象)随着类的加载而加载/运行,类一加载运行,静态成员变量(对象)就运行,立马创建了对象
// 静态与对象共同产生(一般情况下静态先于对象存在)
饿汉单例案例1:
public class Student {
//1.构造方法的私有化,不让外界创建对象, 注意 :这里是无参构造方法私化
private Student(){}
//2. 在其本类里可以创建对象
//2.1此成员变量(即对象),必须要 静态。
//为了不让外界 修改成员变量(即对象)值,加 private 私有化
private static Student s = new Student();
//3提供公共的访问方法, 此方法能够返回此类对象(外界只能通过访问此方法,来获取此类的对象)
//3.1为了确保外界直接访问此方法,此方法静态化
public static Student getStudent(){return s;}
}
public class StudentDemo {
public static void main(String[] args) {
// 通过单例如何如何获得Student类的对象
//静态方法,类名直接调用
Student s1 = Student.getStudent();
Student s2 = Student.getStudent();
System.out.println(s1==s2);}}//true ,说明 s1 s2的地址值相同,指向同一个对象(也只能单例设计模式能做到)
饿汉单例案例2:
JDK的Runtime 类的代码体现了饿汉式单例设计模式 -----类一加载运行,静态成员变量(对象)就运行,立马产生了对象
class Runtime {
//** Don't let anyone else instantiate this class *//*
//构造方法私有
private Runtime() {}
//私有静态,成员变量 对象currentRuntime
private static Runtime currentRuntime = new Runtime();
//对外提供一个公共静态的方法,能够获取此类的对象
public static Runtime getRuntime() { return currentRuntime;}
}
饿汉单例案例3:
银行系统----单例饿汉
public class NumberMachine {
//私有化构造方法, 只有一个对象,不让外界创建对象,对外提供一个方法,可以获取到此对象
private NumberMachine(){}
//自己可以创建对象,私有化对象,不让外界修改对象
//让对象静态化,静态的方法才能调用 //静态的对象,随着类的一加载,对象就产生
private static NumberMachine instance = new NumberMachine();
//对外定义一个方法,返回此类对象, 让外界直接静态调用此方法,
public static NumberMachine getInstance(){ return instance; }
}
五.单例设计模式 --- ----懒汉式
1. 懒汉式:也真是够懒的,直到用的时候,才去创建对象值,
//(一开始不用的时候初始化值为null,到后来用的时候,才创建对象)
* //懒在那? 你不用对象时,对象t=null 为空,, 当你要用的时候,才赋具体的对象值 t-= new Teacher()
* 2. 对外提供的公共访问方法 设为同步方法。
有多条语句操作共享数据,线程执行的代码语句不是原子性,为了确保懒汉式在多线程下的安全性,故设为同步。
懒汉代码体现:
public class Teacher {
//1.构造方法的私有化,不让外界创建对象, 注意 :这里是无参构造方法私化
private Teacher(){}
//懒汉的体现所在,这里对象不赋值 为null
private static Teacher t = null;
//确保懒汉式在多线程下的安全型,这里使用同步方法。
public synchronized static Teacher getTeacher(){
//一开始,对象t 为空, 到用的时候,才赋具体值 t=new Teacher()
if(t==null){t=new Teacher();}
return t;}
}
六.装修设计模式
当想要对已有的对象进行功能增强时,
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象。
并基于被装饰的对象的功能,提供更强的功能。
找到其参数(被装饰的对象。)的共同类型。通过多态的形式,抽取一个具有共同功能的类作为父类,可以装饰更多的子类对象,可以提高扩展性。
装饰模式灵活。避免了继承体系臃肿。
而且降低了类于类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。
所以装饰类和被装饰类通常是都属于一个体系中的父类或一个接口。
下面以一个事例来说明 装饰类的定义和特点
import java.io.*;
class MyBufferedReader extends Reader
{
private Reader r;
MyBufferedReader(Reader r)
{
this.r = r;
}
//可以一次读一行数据的方法。
public String myReadLine()throws IOException
{
//定义一个临时容器。原BufferReader封装的是字符数组。
//为了演示方便。定义一个StringBuilder容器。因为最终还是要将数据变成字符串。
StringBuilder sb = new StringBuilder();
int ch = 0;
while((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
/*
覆盖Reader类中的抽象方法。
*/
public int read(char[] cbuf, int off, int len) throws IOException
{
return r.read(cbuf,off,len) ;
}
public void close()throws IOException
{
r.close();
}
public void myClose()throws IOException
{
r.close();
}
}
class MyBufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("buf.txt");
MyBufferedReader myBuf = new MyBufferedReader(fr);
String line = null;
while((line=myBuf.myReadLine())!=null)
{
System.out.println(line);
}
myBuf.myClose();
}
}
class ZhuangShi
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}