认识设计模式
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;
}
}
package com.wangxing.damnli;
public class TestMain {
public static void main(String[] args) {
/*测试懒汉式的单例模式类
SingleObject1 obj1=SingleObject1.getSingleObject1();
SingleObject1 obj2=SingleObject1.getSingleObject1();
if(obj1==obj2){
System.out.println("相等,同一个对象");
}
if(obj1.equals(obj2)){
System.out.println("相等,同一个对象");
}
System.out.println("obj1=="+obj1.hashCode());
System.out.println("obj2=="+obj2.hashCode());
*/
SingleObject2 obj1=SingleObject2.getSingleObject2();
SingleObject2 obj2=SingleObject2.getSingleObject2();
if(obj1==obj2){
System.out.println("相等,同一个对象");
}
if(obj1.equals(obj2)){
System.out.println("相等,同一个对象");
}
System.out.println("obj1=="+obj1.hashCode());
System.out.println("obj2=="+obj2.hashCode());
}
}
区别
| 懒汉式 | 饿汉式 |
资源利用率 | 好 | 差 |
运行速度 | 差 | 好 |
14.5.什么是工厂模式?
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
1.需求量大
2.牵一发,动全身
有3种角色:
- 工厂角色----【普通类】
- 抽象产品角色---【抽象类/接口】
- 具体产品角色----【抽象类/接口子类】
例如:有农场生产各种水果,有西瓜,有苹果,有香蕉......
农场---工厂角色----【类】
水果---抽象产品角色---【抽象类/接口】
西瓜,苹果,香蕉---具体产品角色----【抽象类/接口子类】
抽象工厂模式---提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
14.6.如何编写简单工厂【静态】模式?
package com.wangxing.factory2;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
/**
* 生产角色对象
* @author Administrator
*
*/
public class FactoryClass {
public static JueSe creatJueSe(String name){
JueSe js=null;
try{
//读取角色列表
//通过readJueSeListMap()方法得到一个装满角色键值对集合
HashMap<String, String> jueseList=readJueSeListMap();
//通过输入的角色名【键】得到对应的【值】
String classname=jueseList.get(name);
//通过创建反射对象的 forName()方法创建对应的反射对象
Class classobj=Class.forName(classname);
//通过反射对象得到实例对象
js=(JueSe)classobj.newInstance();
}catch(Exception e){
e.printStackTrace();
}
return js;
}
/**
*通过此方法得到一个装有角色列表的键值对集合
*/
private static HashMap<String, String> readJueSeListMap() {
HashMap<String, String> jueselist=null;
try{
jueselist=new HashMap<String, String>();
//创建BufferedReader 输入流读取"jueselist.txt"文件
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 infoarry[]=info.split("=");
jueselist.put(infoarry[0], infoarry[1]);
}
//关流
read.close();
in.close();
}catch(Exception e){
e.printStackTrace();
}
return jueselist;
}
}
package com.wangxing.factory2;
/**
* 角色类接口,具有角色公共的性质----攻击
* @author Administrator
*
*/
public interface JueSe {
public void gongjiMethod();
}
package com.wangxing.factory2;
/**
* 战士类----具体产品
* @author Administrator
*
*/
public class ZhanShi implements JueSe{
@Override
public void gongjiMethod() {
System.out.println("我是战士,我使用巨剑攻击!");
}
}
package com.wangxing.factory2;
/**
* 法师类----具体产品
* @author Administrator
*
*/
public class FaShi implements JueSe{
@Override
public void gongjiMethod() {
System.out.println("我是法师,我使用魔杖攻击!");
}
}
package com.wangxing.factory2;
/**
* 弓箭手类----具体产品
* @author Administrator
*
*/
public class GongJianShou implements JueSe{
@Override
public void gongjiMethod() {
System.out.println("我是弓箭手,我使用弓箭攻击!");
}
}
package com.wangxing.factory2;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请选择您要创建的角色:");
String name=input.nextLine();
JueSe js=FactoryClass.creatJueSe(name);
js.gongjiMethod();
}
}
14.7.什么是代理模式?
为其他对象提供一种代理以控制对这个对象的访问。买火车票不一定在火车站买,也可以去代售点。
package com.wangxing.proxy1;
/**
* 提供售票业务的接口
* @author Administrator
*
*/
public interface SellePiaoService {
void maipiao();
}
package com.wangxing.proxy1;
/**
* 火车站
* @author Administrator
*
*/
public class HuoCheZhan implements SellePiaoService{
@Override
public void maipiao() {
System.out.println("我家距离火车站近,我就出火车站买票");
}
}
package com.wangxing.proxy1;
/**
* 代售点
* @author Administrator
*
*/
public class DaiShouDian 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 HuoCheZhan implements SellePiaoService{
@Override
public void maipiao() {
System.out.println("我家距离火车站近,我就出火车站买票");
}
}
package com.wangxing.proxy2;
/**
* 代售点
* @author Administrator
*
*/
public class DaiShouDian extends HuoCheZhan{
@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();
}
}
上面这个实例中体现了静态代理,【父子模式的静态代理】。
静态代理的缺点需要手动创建子类,当需要被代理元素较多的时候,我们的工作量变大了,由于静态代理的上述缺点,所以我们需要一个专门生产代理对象的类。
动态代理--专门由一个类来生产需要被代理的类的代理对象。