认识设计模式
https://www.runoob.com/design-pattern/design-pattern-tutorial.html
14.1.什么是设计模式?
设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结
14.2.设计模式的作用是什么?
使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
14.3.什么是单例模式/单态模式?
单例模式---保证一个类仅有一个实例。
当类被频繁地创建与销毁的时候,我们使用单例模式,这样可以减少了内存的开销,避免对资源的多重占用。
14.4.单例模式的两种表示方式以及区别
1. 懒汉式
package com.wangxing.damnli;
/**
* 懒汉式
* 1.构造方法私有
2.提供一个静态成员变量[私有],用于保存当前类对象
3.提供一个静态方法【公共】返回创建好的当前类对象
4.为了保证在多线程情况下当前类对象只有一个我们就需要添加"synchronized"
* @author Administrator
*
*/
public class SingleObject1 {
private SingleObject1(){}
private static SingleObject1 sobj=null;
//为了保证在多线程情况下当前类对象只有一个我们就需要添加"synchronized"
public static synchronized SingleObject1 getSingleObject1(){
if(sobj==null){
sobj=new SingleObject1();
}
return sobj;
}
}
2. 饿汉式
package com.wangxing.damnli;
/**
* 饿汉式
* 1.构造方法私有
2.提供一个静态成员变量[私有],创建当前类对象
3.提供一个静态方法【公共】返回创建好的当前类对象
4.为了保证在多线程情况下当前类对象只有一个我们就需要添加"synchronized"
* @author Administrator
*
*/
public class SingleObject2 {
private SingleObject2(){}
private static SingleObject2 sobj=new SingleObject2();
public static synchronized SingleObject2 getSingleObject2(){
return sobj;
}
}
区别
|
懒汉式 |
饿汉式 |
资源利用率 |
好 |
差 |
运行速度 |
差 |
好 |
14.5.什么是工厂模式?
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
1.需求量大
2.牵一发,动全身
有3种角色
- 工厂角色----【普通类】
- 抽象产品角色---【抽象类/接口】
- 具体产品角色----【抽象类/接口子类】
例如:有农场生产各种水果,有西瓜,有苹果,有香蕉......
农场---工厂角色----【类】
水果---抽象产品角色---【抽象类/接口】
西瓜,苹果,香蕉---具体产品角色----【抽象类/接口子类】
抽象工厂模式---提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
14.6.如何编写简单工厂【静态】模式?
package com.wangxing.factry;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
/**
* 工厂类【生产角色对象】
* @author Administrator
*
*/
public class FactryClass {
/*
* 生产角色对象
*/
public static JueSe createJueSe(String name){
JueSe js=null;
try{
//读取角色列表
HashMap<String,String> jueseList=readJueSeListMap();
String classname=jueseList.get(name);
Class classobj=Class.forName(classname);
js=(JueSe)classobj.newInstance();
}catch(Exception e){
e.printStackTrace();
}
return js;
}
/**
* 读取角色列表
* @return
*/
private static HashMap<String,String> readJueSeListMap() {
HashMap<String,String> jueselist=null;
try{
jueselist=new HashMap<String,String>();
File file=new File("jueselist.txt");
FileReader in=new FileReader(file);
BufferedReader read=new BufferedReader(in);
String info=null;
while((info=read.readLine())!=null){
String infoarr[]=info.split("=");
jueselist.put(infoarr[0], infoarr[1]);
}
read.close();
in.close();
}catch(Exception e){
e.printStackTrace();
}
return jueselist;
}
}
package com.wangxing.factry;
/**
* 游戏角色接口
* @author Administrator
*
*/
public interface JueSe {
//所有角色具有的公共功能
void gongji();
}
package com.wangxing.factry;
/**
* 战士类【具体产品】
* @author Administrator
*
*/
public class ZhanShi implements JueSe{
@Override
public void gongji() {
System.out.println("我是战士,我使用大刀攻击怪物!");
}
}
package com.wangxing.factry;
/**
* 法师类【具体产品】
* @author Administrator
*
*/
public class FaShi implements JueSe{
@Override
public void gongji() {
System.out.println("我是法师,我使用魔法攻击怪物!");
}
}
package com.wangxing.factry;
import java.util.Scanner;
public class TestMain {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请选择角色:");
String name=input.nextLine();
JueSe js=FactryClass.createJueSe(name);
js.gongji();
}
}
package com.wangxing.factry;
/**
* 弓箭手【具体产品】
* @author Administrator
*
*/
public class JianShou implements JueSe{
@Override
public void gongji() {
System.out.println("我是弓箭手,我使用弓箭攻击怪物!");
}
}
package com.wangxing.factry;
/**
* 刺客类【具体产品】
* @author Administrator
*
*/
public class CiKe implements JueSe{
@Override
public void gongji() {
System.out.println("我是刺客,我使用匕首攻击怪物!");
}
}
战士=com.wangxing.factry.ZhanShi
法师=com.wangxing.factry.FaShi
弓箭手=com.wangxing.factry.JianShou
刺客=com.wangxing.factry.CiKe
14.7.什么是代理模式?
为其他对象提供一种代理以控制对这个对象的访问。
买火车票不一定在火车站买,也可以去代售点。
package com.wangxing.proxy1;
/**
* 提供售票业务的接口
* @author Administrator
*
*/
public interface SellePiaoService {
void maipiao();
}
package com.wangxing.proxy1;
/**
* 代售点
* @author Administrator
*
*/
public class DaiShouDian implements SellePiaoService{
@Override
public void maipiao() {
System.out.println("我家距离火车站远,我就去代售点买票");
}
}
package com.wangxing.proxy1;
/**
* 火车站
* @author Administrator
*
*/
public class HuoCheZhan implements SellePiaoService{
@Override
public void maipiao() {
System.out.println("我家距离火车站近,我就出火车站买票");
}
}
package com.wangxing.proxy1;
public class TestMain {
public static void main(String[] args) {
//根据家距离火车站的远近,决定去什么地方买票
//家距离火车站近,选择火车站
HuoCheZhan hcz=new HuoCheZhan();
hcz.maipiao();
//家距离火车站远,选择代售点
DaiShouDian dsd=new DaiShouDian();
dsd.maipiao();
}
}
上面这个实例中体现了静态代理,【兄弟模式的静态代理】
package com.wangxing.proxy2;
/**
* 提供售票业务的接口
* @author Administrator
*
*/
public interface SellePiaoService {
void maipiao();
}
package com.wangxing.proxy2;
/**
* 代售点
* @author Administrator
*
*/
public class DaiShouDian extends HuoCheZhan{
@Override
public void maipiao() {
System.out.println("我家距离火车站远,我就去代售点买票");
}
}
package com.wangxing.proxy2;
/**
* 火车站
* @author Administrator
*
*/
public class HuoCheZhan implements SellePiaoService{
@Override
public void maipiao() {
System.out.println("我家距离火车站近,我就出火车站买票");
}
}
package com.wangxing.proxy2;
public class TestMain {
public static void main(String[] args) {
//根据家距离火车站的远近,决定去什么地方买票
//家距离火车站近,选择火车站
HuoCheZhan hcz=new HuoCheZhan();
hcz.maipiao();
//家距离火车站远,选择代售点
DaiShouDian dsd=new DaiShouDian();
dsd.maipiao();
}
}
上面这个实例中体现了静态代理,【父子模式的静态代理】
静态代理的缺点需要手动创建子类,当需要被代理元素较多的时候,我们的工作量变大了。
由于静态代理的上述缺点,所以我们需要一个专门生产代理对象的类
动态代理--专门由一个类来生产需要被代理的类的代理对象。
有2中方式
JDK动态代理----通过java.lang.reflect Class Proxy类来创建代理类对象。
【只能为实现过某个接口的java类提供代理类对象】
CGlib代理-------CGlib是一个第三发的开发包,用的时候需要自己事先下载导入到项目中
【所有的java类提供代理类对象】