------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
设计模式
一工厂设计模式
1、作用
工厂设计模式的作用:有一个专门用于生产对象的方法。
2、工厂设计模式的书写方法
创建一个框架用于根据产配置文件产生任意类型的对象。
步骤:
1、创建一个BufferReader读取配置文件。
2、根据读取到的完整类名通过forName(String s)创建Class对象
3、通过newInstance()获取Object对象
4、通过BufferedReader读取配置文件获取成员的名称和值
5、通过getDeclareField()获取成员变量
6、通过getType()判断成员变量的类型,并通过set(Obj,value)给对象成员变量赋值
3、工厂设计模式的代码
package it.heima.design;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
//工厂设计模式,有一个专门用于生产对象的方法
public class FactoryDemo {
public static void main(String[] args) throws Exception {
Object obj=Factory.getInstance();
System.out.println(obj);
}
}
class Factory{
public static Object getInstance() throws IOException, Exception{
BufferedReader bufferedReader=new BufferedReader(new FileReader("E:\\JavaSE_WorkSpace\\AllTest\\src\\it\\heima\\design\\properties.txt"));
String className=null; //获取类名
className=bufferedReader.readLine(); //读第一行获取类对象
Class clazz=Class.forName(className);
Object obj=clazz.newInstance(); //创建该类对象
String line=null; //给对象设置值
while((line=bufferedReader.readLine())!=null){
String[] datas=line.split("="); //properties的内容都是键值对,用=分割
//获取成员
Field field=clazz.getDeclaredField(datas[0]);
field.setAccessible(true); //成员一般是私有的,要暴力反射
if(field.getType()==int.class){ //获取成员类型,进行转换再复制
field.set(obj, Integer.parseInt(datas[1]));
}if(field.getType()==String.class){
field.set(obj, datas[1]);
}else if(field.getType()==boolean.class){
field.setBoolean(obj, Boolean.valueOf(datas[1]));
}
}
return obj;
}
}
二、观察者设计模式
1、观察者设计模式的作用
当一件事情发生后,要通知另一个对象来对这件事情做出反应。
同时,使用接口可以降低类与类之间的耦合。
2、观察者设计模式的步骤
1、创建事件类,并产生事件
2、创建观察者接口
3、事件类维护了观察者接口的对象,并用该对象来调用方法。
4、被通知类实现该接口,并重写该方法
5、主类中将事件类中的观察者对象实例化
6、调用事件类的方法
3、观察者设计模式的代码
天气台案例,天气台产生天气,并通知其他类来做出相应的动作
被通知者:
package it.heima.design;
public class Student implements NotifyWeather{
<span style="white-space:pre"> </span>private int id;
<span style="white-space:pre"> </span>private String name;
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void notifyWeather(String weather) {
<span style="white-space:pre"> </span>//<span style="white-space:pre"> </span>String[] weather={"下雨","下雪","地震","龙卷风","晴天","干旱"};
<span style="white-space:pre"> </span>if("下雨".equals(weather)){
<span style="white-space:pre"> </span>System.out.println(name+"打伞出去了");
<span style="white-space:pre"> </span>}else if("下雪".equals(weather)){
<span style="white-space:pre"> </span>System.out.println(name+"被冻住了");
<span style="white-space:pre"> </span>}else if("地震".equals(weather)){
<span style="white-space:pre"> </span>System.out.println(name+"躲地洞里去了");
<span style="white-space:pre"> </span>}else if("晴天".equals(weather)){
<span style="white-space:pre"> </span>System.out.println(name+"出门玩了");
<span style="white-space:pre"> </span>}else if("龙卷风".equals(weather)){
<span style="white-space:pre"> </span>System.out.println(name+"被吹走了");
<span style="white-space:pre"> </span>}else if("干旱".equals(weather)){
<span style="white-space:pre"> </span>System.out.println(name+"热成狗了");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public String toString() {
<span style="white-space:pre"> </span>return "编号=" + id + ",姓名=" + name ;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public Student() {
<span style="white-space:pre"> </span>super();
<span style="white-space:pre"> </span>// TODO Auto-generated constructor stub
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public Student(int id, String name) {
<span style="white-space:pre"> </span>super();
<span style="white-space:pre"> </span>this.id = id;
<span style="white-space:pre"> </span>this.name = name;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>
}
事件类:
package it.heima.design;
import java.util.ArrayList;
import java.util.Random;
public class WeatherStation {
String[] weather={"下雨","下雪","地震","龙卷风","晴天","干旱"};
String currentWeather; //当前天气
ArrayList<NotifyWeather> arrayList=new ArrayList<>(); //维护一个接口集合,谁实现它,谁就能调用方法
Random random =new Random();
int index; //天气索引
int sleepTime; //间隔时间
public void work(){
while(true){
index=random.nextInt(weather.length);
currentWeather=weather[index];
System.out.println("当前天气是:"+currentWeather);
for(NotifyWeather item: arrayList){
item.notifyWeather(currentWeather);
}
sleepTime=random.nextInt(501)+1000;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void startWork(){
new Thread(){
public void run(){
work();
}
}.start();
}
}
接口:
package it.heima.design;
public interface NotifyWeather {
public abstract void notifyWeather(String weather);
}
主类:
package it.heima.design;
public class ObserverDemo {
public static void main(String[] args) {
WeatherStation station=new WeatherStation();
Student s1=new Student(101, "张三");
station.arrayList.add(s1);
Student s2=new Student(102, "李四");
station.arrayList.add(s2);
station.startWork();
}
}
三、单例设计模式
1、单例设计模式的作用
某些类只有一个对象,不允许创建其他对象时就采用单例设计模式。
2、单例设计模式有两类
懒汉单例设计模式和饿汉单例设计模式。
3、代码演示
饿汉单例设计模式:
package it.heima.design;
//饿汉单例设计模式
public class SingletonDemo {
public static void main(String[] args) {
Person p1=Person.getInstance();
Person p2=Person.getInstance();
System.out.println("是同一个对象吗?"+(p1==p2));
}
}
class Person{
private static Person p = new Person();
private Person(){
}
public static Person getInstance(){
return p;
}
}
改进版懒汉单例设计模式
package it.heima.design;
//懒汉单例设计模式改进
public class SingletonDemo2 {
public static void main(String[] args) {
People p = People.getInstance();
People p2 = People.getInstance();
System.out.println("是同一个对象吗?" + (p == p2));
}
}
class People {
private static People p;
private People() {
}
public static People getInstance() {
if (p == null) {
synchronized ("锁") {
if (p == null) {
p = new People();
}
}
}
return p;
}
}
通过同步代码块解决线程安全问题,同时多加一层判断语句以提升效率。
四、装饰者设计模式
有点类似递归。层层调用
1、装饰者设计模式的使用步骤
1、多个装饰类继承同一个被装饰类
2、每个装饰类维护一个被装饰类的对象
3、通过构造函数给被装饰类对象赋值
4、重写方法,通过被装饰对象调用同名的父类方法,并装饰
5、返回一个值
2、给BufferedReader的ReaderLine()添加行号演示
package it.heima.design;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class DecoratorDemo {
public static void main(String[] args) throws IOException {
BufferedLineNumber bufferedLineNumber=new BufferedLineNumber(new BufferedReader(new FileReader("F:\\方舟进化\\补丁\\ARK.Survival.Evolved.Up149.v207.0-v208.3.Crack\\ARK.Survival.Evolved.Up149.v207.0-v208.3.Crack\\changelog.txt")));
BufferedLineNumber2 bufferedLineNumber2=new BufferedLineNumber2(bufferedLineNumber);
String line=null;
while((line=bufferedLineNumber2.readLine())!=null){
System.out.println(line);
}
}
}
class BufferedLineNumber extends BufferedReader{
private static BufferedReader bufferedReader;
int linNum=1;
public BufferedLineNumber(BufferedReader bufferedReader){
super(bufferedReader);//该语句没有任何作用。因为父类没有无参构造会报错,所以传入一个Reader
this.bufferedReader=bufferedReader;
}
public String readLine() throws IOException{
String line=bufferedReader.readLine();
if(line==null){
return null;
}
line=linNum+": "+line;
linNum++;
return line;
}
}
class BufferedLineNumber2 extends BufferedReader{
private BufferedReader bufferedReader;
public BufferedLineNumber2(BufferedReader bufferedReader){
super(bufferedReader);
this.bufferedReader=bufferedReader;
}
public String readLine() throws IOException{
String line=null;
line = bufferedReader.readLine();
if(line==null){
return null;
}
line="第"+line;
return line;
}
}
五、模板设计模式
1、模板设计模式的作用
当我们解决某些事情,一部分步骤是固定的,一部分步骤是会改变的,就将会改变的部分用抽象函数封装起来。
2、模板设计模式的步骤
1、创建模板类,定义一个抽象方法
2、模板类中定义一个方法A,调用了抽象方法
3、创建一个类继承模板类,重写抽象方法,并调用方法A
3、模板设计模式代码演示
package it.heima.design;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ModelDemo extends Collection{
public static void main(String[] args) {
ModelDemo demo=new ModelDemo();
demo.collect();
}
public void code(){
for(int i=0;i<2;i++){
System.out.println("我是模板");
}
}
}
abstract class Collection{
public void collect(){
Date date=new Date();
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
long time=System.currentTimeMillis();
System.out.println(dateFormat.format(date));
System.out.println("startTime:"+time );
code(); //变化的部分用抽象函数提取
time=System.currentTimeMillis();
System.out.println("endTime:"+time);
}
public abstract void code();
}