Java基础---单例模式 观察者模式 反射 工厂模式

package cn.itcast.single;


/*
 单例设计模式:
 
  懒汉单例设计模式(线程安全问题 的解决方案):
  步骤:
  1. 私有化构造函数。
  2. 声明本类引用类型变量,但是不要创建对象。
  3. 声明一个公共静态的方法获取本类的对象,获取之前先判断是否已经创建了本类的对象了,如果已经创建了
  就不要在创建直接返回即可,如果还没有创建,那么就先创建本类的引用类型变量,然后再返回。
 
 */


//懒汉单例设计模式
class Single{

// 声明本类引用类型变量,但是不要创建对象。
private static Single s;

//私有化构造函数
private Single(){}

// 声明一个公共静态的方法获取本类的对象
public static Single getInstance(){
if(s==null){
synchronized ("锁") {
if(s==null){
s = new Single();
}
}
}
return s;
}

}
















public class Demo1 {


}



观察者模式




package cn.itcast.observer;


import java.util.ArrayList;
import java.util.Random;
/*
 观察者设计模式:观察者设计模式解决的问题时当一个对象发生指定的动作时,要通过另外一个对象做出相应的处理。
 
需求: 编写一个气象站、一个工人两个类,当气象站更新天气 的时候,要通知人做出相应的处理。
  


 问题1: 气象站更新了多次天气,然后人才做一次的处理。
 
问题2: 目前气象站只能通知一个人而已。


问题3: 在现实生活中出了工人群体要关注天气,其他 的群体也需要关注天气




观察者设计模式的步骤:
1. 当前目前对象发生指定的动作是,要通知另外一个对象做出相应的处理,这时候应该把对方的相应处理方法定义在接口上。
2. 在当前对象维护接口的引用,当当前对象发生指定的动作这时候即可调用接口中的方法了。




 */


//气象站
public class WeatherStation {

String[] weathers = {"晴天","雾霾","刮风","冰雹","下雪"};

//当前天气
String  weather ;

//该集合中存储的都是需要收听天气预报的人
ArrayList<Weather> list = new ArrayList<Weather>();  //程序设计讲究低耦合---->尽量不要让一个类过分依赖于另外一个类。



public void addListener(Weather e){
list.add(e);
}


//开始工作
public void startWork() {
final Random random = new Random();

new Thread(){
@Override
public void run() {
while(true){ 
updateWeather(); // 每1~1.5秒更新一次天气  1000~1500
for(Weather e : list){
e.notifyWeather(weather);
}


int  s = random.nextInt(501)+1000; //  500
try {
Thread.sleep(s);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}.start();

}



//更新天气的 方法
public void updateWeather(){
Random random = new Random();
int index = random.nextInt(weathers.length);
weather = weathers[index];
System.out.println("当前的天气是: " + weather);
}

}

package cn.itcast.observer;




import java.util.Random;


public class WeatherMain {


public static void main(String[] args) throws Exception {
//工人
Emp e = new Emp("小明");
Emp e2 = new Emp("如花");

//学生
Student s1 = new Student("狗娃");
Student s2 = new Student("狗剩");


WeatherStation station = new WeatherStation();
station.addListener(e);
station.addListener(e2);
station.addListener(s1);
station.addListener(s2);



station.startWork();


}

}





package cn.itcast.observer;




public class Student implements Weather{

String name;


public Student(String name) {
super();
this.name = name;
}


public void notifyWeather(String weather){
if("晴天".equals(weather)){
System.out.println(name+"高高兴兴的去开学!!");
}else if("雾霾".equals(weather)){
System.out.println(name+"吸多两口去上学!");
}else if("刮风".equals(weather)){
System.out.println(name+"在家睡觉!");
}else if("冰雹".equals(weather)){
System.out.println(name+"在家睡觉!");
}else if("下雪".equals(weather)){
System.out.println(name+"等下完再去上学!");
}



}

}






package cn.itcast.observer;
//人 是要根据天气做出相应的处理的。
public class Emp implements Weather{

String name;


public Emp(String name) {
this.name = name;
}


//人是要根据天气做出相应的处理的。  "晴天","雾霾","刮风","冰雹","下雪"
public void notifyWeather(String weather){
if("晴天".equals(weather)){
System.out.println(name+"高高兴兴的去上班!!");
}else if("雾霾".equals(weather)){
System.out.println(name+"戴着消毒面具去上班!");
}else if("刮风".equals(weather)){
System.out.println(name+"拖着大石头过来上班!");
}else if("冰雹".equals(weather)){
System.out.println(name+"戴着头盔过来上班!");
}else if("下雪".equals(weather)){
System.out.println(name+"戴着被子过来上班!");
}



}


}





package cn.itcast.observer;
//订阅天气预报的接口
public interface Weather {


public void notifyWeather(String weather);


}





反射 工厂



package cn.itcast.reflect;


/*
反射: 当一个字节码文件加载到内存的时候,jvm会对该字节码进行解剖,然后会创建一个对象的Class对象,把字节码文件的信息全部都
存储到该Class对象中,我们只要获取到Class对象,我们就可以使用字节码对象设置对象的属性或者调用对象的方法等操作....


注意: 在反射技术中一个类的任何成员都有对应 的类进行描述。  比如:  成员变量(Field)   方法----> Method类  


*/
public class Demo1 {

Person p;

public static void main(String[] args) throws ClassNotFoundException {
//Person p = new Person(110,"狗娃");

//推荐使用: 获取Class对象的方式一
Class clazz1 = Class.forName("cn.itcast.reflect.Person");
System.out.println("clazz1:"+ clazz1);


//获取Class对象的方式二: 通过类名获取
Class clazz2 = Person.class;
System.out.println("clazz1==clazz2?"+ (clazz1==clazz2));


//获取Class对象的方式三 :通过对象获取
Class clazz3 = new Person(110,"狗娃").getClass();
System.out.println("clazz2==clazz3?"+ (clazz2==clazz3));

}

}




package cn.itcast.reflect;


import java.lang.reflect.Constructor;


/*
 如何通过Class对象获取构造方法。
 */
public class Demo2 {

public static void main(String[] args) throws Exception {
//获取到对应的Class对象
Class clazz = Class.forName("cn.itcast.reflect.Person");

//通过Class对象获取对应的构造方法
/*Constructor[] constructors = clazz.getConstructors();  // getConstructors()获取一个类的所有公共的构造方法
for(Constructor constructor : constructors){
System.out.println(constructor);
}

Constructor[] constructors =  clazz.getDeclaredConstructors(); //获取到一个类的所有构造方法,包括私有的在内 。
for(Constructor constructor : constructors){
System.out.println(constructor);
}
*/

/*Constructor constructor = clazz.getConstructor(int.class,String.class);  // getConstructor 获取单个指定的构造方法。
Person p  = (Person) constructor.newInstance(999,"小城"); // newInstance()创建一个对象
System.out.println(p);*/



//获取私有的构造函数
Constructor constructor =  clazz.getDeclaredConstructor(null);
//暴力反射
constructor.setAccessible(true);
Person p  =(Person) constructor.newInstance(null);
System.out.println(p);


}


}





package cn.itcast.reflect;


import java.lang.reflect.Method;


/*
 通过Class对象获取到对应的方法。
 
 在反射技术中使用了Method类描述了方法的。
 
 */
public class Demo3 {

public static void main(String[] args) throws Exception {
//获取到对应的Class对象
Class clazz = Class.forName("cn.itcast.reflect.Person");
//获取到所有公共的方法
/*Method[] methods = clazz.getMethods(); // getMethods() 获取所有 的公共方法而已。
Method[] methods = clazz.getDeclaredMethods(); //获取到所有的方法,但是不包含父类的方法。
for(Method method  : methods){
System.out.println(method);
}*/

Person p = new Person(110,"狗娃");
/*
Method m = clazz.getMethod("eat", int.class);
m.invoke(p, 3); //invoke 执行一个方法。 第一个参数:方法的调用对象。 第二参数: 方法所需要的参数。


//执行私有的方法
Method m =clazz.getDeclaredMethod("sleep",int.class);
//设置访问权限允许访问
m.setAccessible(true);
m.invoke(null, 6);*/

Method m = clazz.getMethod("sum", int[].class);
m.invoke(p,new int[]{12,5,9});

}



}





package cn.itcast.reflect;


import java.lang.reflect.Field;
/*
 通过反射获取对应的成员变量
 
 在反射技术中使用了Field类描述了成员变量的。
 
 */


public class Demo4 {


public static void main(String[] args) throws Exception {
//获取到对应的Class对象
Class clazz = Class.forName("cn.itcast.reflect.Person");
//获取 到所有的成员变量
/*Field[] fields = clazz.getDeclaredFields();
for(Field field  : fields){
System.out.println(field);
}*/
Person p = new Person();
Field field = clazz.getDeclaredField("id");
//设置访问权限可以访问
field.setAccessible(true);
field.set(p, 110); //第一个参数: 设置该数据 的成员变量, 第二个参数:属性值。
System.out.println(p);
}


}





package cn.itcast.reflect;


public class Person {

private int id;

String name;

public Person(int id,String name){
this.id = id;
this.name = name;
}

public Person(){}


public void eat(int num){
System.out.println(name+"吃很"+num+"斤饭");
}

private static void sleep(int num){
System.out.println("明天睡上"+num+"小时");
}


public static void  sum(int[] arr){
System.out.println("长度是:"+ arr.length);
}


@Override
public String toString() {
return " 编号:"+ this.id +" 姓名:"+ this.name;
}

}





package cn.itcast.factory;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;


import cn.itcast.reflect.Person;


/*
工厂设计模式就是用于产生对象 的。
*/
class Car{}


class BMW extends Car{}


class BSJ extends Car{}






public class Demo1 {


public static void main(String[] args) throws Exception {
Person p = (Person) getInstance();
System.out.println(p);
}

//需求: 编写一个工厂方法根据配置文件返回对应的对象。
public static Object getInstance() throws Exception{
//读取配置文件
BufferedReader bufferedReader = new BufferedReader(new FileReader("info.txt"));
//读取第一行 : 读取类文件的信息
String className = bufferedReader.readLine();
//通过完整类名获取对应 的Class对象
Class clazz = Class.forName(className);
//获取到对应的构造方法
Constructor constructor = clazz.getDeclaredConstructor(null);
constructor.setAccessible(true);
Object o  = constructor.newInstance(null);
//给对象设置对应的属性值
String line = null;
while((line = bufferedReader.readLine())!=null){
String[] datas = line.split("=");
Field field =clazz.getDeclaredField(datas[0]);
//设置可以访问
field.setAccessible(true);
if(field.getType()==int.class){
field.set(o, Integer.parseInt(datas[1]));
}else{
field.set(o, datas[1]);
}
}
return o;

}


}

猜你喜欢

转载自blog.csdn.net/sophiaviayang/article/details/77471258