目录
一、概要
Java设计模式是软件开发中一套被广泛使用的、解决特定问题的通用解决方案。
这些模式包括单例模式、工厂模式、原型模式、建造者模式、适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、策略模式、模板方法模式、命令模式、观察者模式和中介者模式等。每种模式都描述了一个在周围不断重复发生的问题及其核心解决方案,例如,单例模式确保一个类只有一个实例,而工厂模式则通过封装对象的创建过程来简化客户端的代码。
二、什么是设计模式
- 在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人在1990年代从建筑设计领域引入到计算机科学的。
- Richard Helm, Ralph Johnson ,John Vlissides (Gof)
- 《设计模式:可复用面向对象软件的基础》 收录 23种模式
- 观察者模式
- 策略模式
- 装饰者模式
- 享元模式
- 模板方法
- 其他
- 架构模式
- MVC
- 分层
- 设计模式
- 提炼系统中的组件
- 代码模式(成例 Idiom)
- 低层次,与编码直接相关
- 如DCL
class Person {
String name;
int birthYear;
byte[] raw;
public boolean equals(Object obj) {
if (!obj instanceof Person)
return false;
Person other = (Person)obj;
return name.equals(other.name) && birthYear == other.birthYear &&
Arrays.equals(raw,other.raw);
}
public int hashCode() {
//...
}
}
三、单例模式
- 单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为,比如:全局信息配置
public class Singleton {
private Singleton()
{
System.out.println("Singleton is create");
}
private static Singleton instance = new Singleton();
public static Singleton getInstance()
{
return instance;
}
}
public class Singleton2 {
public static int STATUS=1; private Singleton(){
System.out.println("Singleton is create");
}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
// 何时产生实例 不好控制
四、不变模式
- 一个类的内部状态创建后,在整个生命期间都不会发生变化时,就是不变类
- 不变模式不需要同步
// 创建对象时,必须指定数据
public final class Product {
//确保无子类
private final String no;
//私有属性,不会被其他对象获取
private final String name;
//final保证属性不会被2次赋值
private final double price;
public Product(String no, String name, double price) { super();
//因为创建之后,无法进行修改this.no = no;
this.name = name;
this.price = price;
}
public String getNo() {
return no;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
- java.lag.String
- java.lang.Boolean
- java.lang.Byte
- java.lang.Character
- java.lang.Double
- java.lang.Float
- java.lang.Integer
- java.lang.Long
- java.lang.Short
五、Futura模式
- 核心思想是异步调用
public interface Data {
public String getResult ();
}
public class FutureData implements Data {
protected RealData realdata = null; //FutureData是RealData的包装
protected boolean isReady = false;
public synchronized void setRealData(RealData realdata) {
if (isReady) {
return;
}
this.realdata = realdata;
isReady = true;
notifyAll(); //RealData已经被注入,通知getResult()
}
public synchronized String getResult() { //会等待RealData构造完成
while (!isReady) {
try {
wait(); //一直等待,知道RealData被注入
} catch (InterruptedException e) {
}
}
return realdata.result; //由RealData实现
}
}
public class RealData implements Data { protected final String result;
public RealData(String para) {
//RealData的构造可能很慢,需要用户等待很久,这里使用sleep模拟StringBuffer sb=new StringBuffer();
for (int i = 0; i < 10; i++) {
sb.append(para); try {
//这里使用sleep,代替一个很慢的操作过程Thread.sleep(100);
} catch (InterruptedException e) {
}
}
result =sb.toString();
}
public String getResult() { return result;
}
}
public class Client {
public Data request(final String queryStr) { final FutureData future = new FutureData(); new Thread() {
public void run() {// RealData的构建很慢,
//所以在单独的线程中进行
RealData realdata = new RealData(queryStr); future.setRealData(realdata);
}
}.start();
return future; // FutureData会被立即返回
}
}
public static void main(String[] args) { Client client = new Client();
//这里会立即返回,因为得到的是FutureData而不是RealData
Data data = client.request("name");
System.out.println("请求完毕"); try {
//这里可以用一个sleep代替了对其他业务逻辑的处理
//在处理这些业务逻辑的过程中,RealData被创建,从而充分利用了等待时间
Thread.sleep(2000);
} catch (InterruptedException e) {
}
//使用真实的数据
System.out.println("数据 = " + data.getResult());
}
JDK对Future模式的支持
public class RealData implements Callable<String> {
private String para;
public RealData(String para){
this.para=para;
}
@Override
public String call() throws Exception {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 10; i++) {
sb.append(para);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
return sb.toString();
}
}
public class FutureMain {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//构造FutureTask
FutureTask<String> future = new FutureTask<String>(new RealData("a"));
ExecutorService executor = Executors.newFixedThreadPool(1);
//执行FutureTask,相当于上例中的 client.request("a") 发送请求
//在这里开启线程进行RealData的call()执行
executor.submit(future);
System.out.println("请求完毕");
try {
//这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
Thread.sleep(2000);
} catch (InterruptedException e) {
}
//相当于data.getResult (),取得call()方法的返回值
//如果此时call()方法没有执行完成,则依然会等待
System.out.println("数据 = " + future.get());
}
}
public class FutureMain2 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(1);
//执行FutureTask,相当于上例中的 client.request("a") 发送请求
//在这里开启线程进行RealData的call()执行
Future<String> future=executor.submit(new RealData("a"));
System.out.println("请求完毕");
try {
//这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
Thread.sleep(2000);
} catch (InterruptedException e) {
}
//相当于data.getResult (),取得call()方法的返回值
//如果此时call()方法没有执行完成,则依然会等待
System.out.println("数据 = " + future.get());
}
}
六、生产者消费者模式
生产者-消费者模式是一个经典的多线程设计模式。它为多线程间的协作提供了良好的解决方案。
在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务。生产者和消费者之间则通过共享内存缓冲区进行通信