javajavase
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式
创建型模式,共五种
- 工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式,共七种
- 适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式,共十一种
- 策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
单例设计模式
某个类在整个系统中,只有唯一的一个对象
形式
饿汉式
class Single{
// 内部创建类的对象
// 要求此对象也必须声明为静态的
private static Single instance = new Single();
// 私有化类的构造器
private Single(){
}
// 提供公共的静态的方法,返回类的对象
public static Single getInstance(){
return instance;
}
}
- 坏处:对象加载时间过长
- 好处:饿汉式是线程安全的
懒汉式
class Single{
// 声明当前类对象,没有初始化
// 此对象也必须声明为static的
private static Single instance = null;
// 私有化类的构造器
private Single(){
}
// 声明public、static的返回当前类对象的方法
public static Single getInstance(){
if(instance == null){
instance = new Single();
}
return instance;
}
}
- 好处:延迟对象的创建
目前的写法坏处:线程不安全
//线程安全
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
应用场景
枚举
- 网站的计数器
- 应用程序的日志应用
- 数据库连接池
- 读取配置文件的类
- JDK Runtime类
- Application 也是单例的典型应用
- Windows的Task Manager (任务管理器)
- Windows的Recycle Bin (回收站)
模板设计模式
特征
- 当功能内部一部分实现是确定的,一部分实现是不确定的。可以把不确定的部分暴露出去,让子类去实现
- 在父类中能确定某个功能的整体的算法结构,但是对于其中的某个步骤,在父类中无法确定,要延迟到子类中去实现,这个时候就可以通过模板设计模式
属于抽象类的应用
abstract class BankTemplateMethod {
// 具体方法
public void takeNumber() {
System.out.println("取号排队");
}
// 办理具体的业务 //钩子方法
public abstract void transact();
public void evaluate() {
System.out.println("反馈评分");
}
// 模板方法,把基本操作组合到一起,子类一般不能重写
public final void process() {
this.takeNumber();
this.transact();// 像个钩子,具体执行时,挂哪个子类,就执行哪个子类的实现代码
this.evaluate();
}
}
class DrawMoney extends BankTemplateMethod {
public void transact() {
System.out.println("我要取款!!!");
}
}
class ManageMoney extends BankTemplateMethod {
public void transact() {
System.out.println("我要理财!我这里有2000万美元!!");
}
}
public class TemplateMethodTest {
public static void main(String[] args) {
BankTemplateMethod btm = new DrawMoney();
btm.process();
BankTemplateMethod btm2 = new ManageMoney();
btm2.process();
}
}
常见
- 数据库访问的封装
- Junit单元测试
- JavaWeb的Servlet中关于doGet/doPost方法调用
- Hibernate中模板程序
- Spring中JDBCTemlate、HibernateTemplate等
代理模式
为其他对象提供一种代理以控制对这个对象的访问
实现AOP的基础
静态代理
三个角色
- 主题(接口):代理类与被代理类必须都实现主题接口
- 被代理类
- 代理类:必须持有被代理类对象的引用 ```java interface Star { void confer();// 面谈 void signContract();// 签合同 void bookTicket();// 订票 void sing();// 唱歌 void collectMoney();// 收钱 }
//被代理类 class RealStar implements Star { public void confer() { } public void signContract() { } public void bookTicket() { } public void sing() { System.out.println(“明星:歌唱~~~”); } public void collectMoney() { } }
//代理类 class Proxy implements Star { private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("经纪人面谈");
}
public void signContract() {
System.out.println("经纪人签合同");
}
public void bookTicket() {
System.out.println("经纪人订票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
public class StaticProxyTest { public static void main(String[] args) { Proxy s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
<a name="Kctji"></a>
### [动态代理](https://www.yuque.com/u1135564/javase/ghb2oa#AXOvD)(反射详细讲解)
三个角色
- 主题(接口):代理类与被代理类必须都实现主题接口
- 被代理类
- 代理类:代理类的创建方式变了,由类加载器对象,在运行时产生
要点
- 主题:和静态代理模式一样,就是一个接口
- 被代理类
- 和静态代理模式一样,实现了主题的一个实现类
- 负责核心业务逻辑代码
- 处理器
- 用来描述,代理类要做的工作
- 持有被代理类的对象的引用
- 必须实现一个InvocationHandler接口
- 重写一个public Object invoke(Object proxy,Method method,Object[] args)
- 动态的创建代理类或代理类的对象
- Proxy.newProxyInstance(被代理类的类加载器,被代理类实现的所有接口,处理器对象);
- 被代理类的类加载器,用来动态的在内存中生成代理类的Class对象用,即动态生成代理类
- 生成代理类时,要和被代理类实现同样的接口
应用
- 安全代理:屏蔽对真实角色的直接访问
- 远程代理:通过代理类处理远程方法调用(RMI)
- 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象
---
<a name="ECZLP"></a>
## 工厂设计模式
[拓展:工厂设计模式.pdf](https://www.yuque.com/attachments/yuque/0/2021/pdf/1379492/1618995091089-682c1dce-2f3c-43d4-a0d3-37d7f1b8d0e5.pdf)
- 目的:使得使用者与创建者分离——把创建某些接口的实现类对象交给工厂来做
<a name="R6OYU"></a>
### 简单工厂
![image.png](https://cdn.nlark.com/yuque/0/2021/png/1379492/1625558213462-cbd07db9-000e-4bda-9b4f-284b9a3e8432.png#clientId=uf039f5d4-2356-4&from=paste&id=u868a0ec3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=816&originWidth=2258&originalType=url&ratio=1&size=546169&status=done&style=shadow&taskId=ucd5a1e33-48c6-4fec-b49f-12c1d228278)
```java
//1、所有的要创建的对象,都是符合某个标准的
interface Car {
void run();
}
class BMW implements Car {
public void run(){
...
}
}
class Benz implements Car {
public void run(){
...
}
}
//2、设计一个工厂类,用来创建各种各样的Car的实现类的对象
class CarFactory {
public static Car getCar(String name) {
if("宝马".equals(name)) {
return new BMW();
}else if("奔驰".equals(name)) {
return new Benz();
}
return null;
}
}
- 优点:代码简洁
- 缺点:当增加新产品时,需要修改工厂方法,违反了“对修改关闭,对扩展开放”的原则
工厂方法模式
```java //1、所有的要创建的对象,都是符合某个标准的 interface Car{ void run(); }
class BMW implements Car{
public void run(){
….
}
}
class Benz implements Car{
public void run(){
….
}
}
//2、每一种产品都自己的工厂生产 //所有的工厂就有共同的特征 interface Factory{ Car getCar(); }
class BMWFactory implements Factory{ public BMW getCar(){ return new BMW(); } }
class BenzFactory implements Factory{ public Benz getCar(){ return new Benz(); } } ```