java常用的设计模式
前言:设计模式的六大原则
- 开闭原则
对扩展开放,对修改关闭(尽可能对代码少修改)。 - 里氏替换原则
它是面向对象基本原则之一,任何父类(基类)出现的地方,子类都可以出现,也就是子类可以替换父类的任何功能(体现了父类的可扩展性)。 - 依赖倒转原则
尽可能面向接口编程,依赖接口而不依赖类。 - 接口隔离原则
一个类如果能实现多个接口,尽可能实现多个,为了降低依赖,降低耦合。 - 最少知道原则
一个实体尽可能少的与其他实体产生相互关联关系,将实体的功能独立。 - 合成复用原则
尽量使用合成,聚合的方式,而不使用继承。
1、单例模式
单例模式是保证一个类在内存中只能存在一个对象。它分为懒汉式和饿汉式。
- 懒汉式 :
懒汉式是线程不安全的,在为了保证线程安全的情况下,需要加入禁止指令重排与双重校验。
public class ConnectionPool {
/*
volatile:
在多线程的时候,cpu有共享内存,所有线程都能看到共享内存的最新状
态,保证内存可见和一致性。
解决了在下面创建对象时,设置实例指向内存空间与初始化对象的乱序问
题。
*/
private volatile static ConnectionPool instance = null;
// 防止反射
private static boolean isFristCreate = true;
private ConnectionPool() {
if (isFristCreate) {
synchronized (ConnectionPool.class) {
if (isFristCreate) {
isFristCreate = false;
}
}
} else {
throw new RuntimeException("已然被实例化一次,不能再实例化");
}
}
public synchronized static ConnectionPool getInstance() {
if (instance == null) {
synchronized (ConnectionPool.class) {
if (instance == null) {
instance = new ConnectionPool();
}
}
}
return instance;
}
}
- 饿汉式
JVM在类加载的过程,保证了不会初始化多个static对象,只会加载一次,所以饿汉式单例模式式线程安全的。
public class ConnectionPool {
// 私有化构造器
private ConnectionPool() {}
// 提供一个实例
private static ConnectionPool instance = new ConnectionPool();
// 提供共有的方法返回实例
public static ConnectionPool getInstance() {
return instance;
}
}
2、工厂模式
//笔的接口
public interface Pen {
public void write();
}
//圆珠笔
public class BallPen implements Pen {
@Override
public void write() {
System.out.println("这是圆珠笔");
}
}
//铅笔
public class Pencil implements Pen {
@Override
public void write() {
System.out.println("这是铅笔");
}
}
//工厂
public class PenFactory {
/**
* 根据不同的类型 生产不同的产品
* @param type
* @return
*/
public Pen produce(String type){
Pen pen = null;
if(type.equals("ballPen")){
pen = new BallPen();
}else if(type.equals("pencil")){
pen = new Pencil();
}else{
System.out.println("不能生产");
}
return pen;
}
}
3、建造者模式
public class Car {
private final String steeringWheel;//必须
private final String wheel;//必须
private final String glass;//可选
private final String lamp;//可选
private Car(Builder builder) {
this.steeringWheel = builder.steeringWheel;
this.wheel = builder.wheel;
this.glass = builder.glass;
this.lamp = builder.lamp;
}
public static class Builder {
private String steeringWheel;//必须
private String wheel;//必须
private String glass;//可选
private String lamp;//可选
public Builder(String steeringWheel, String wheel) {
this.steeringWheel = steeringWheel;
this.wheel = wheel;
}
public Builder setGlass(String glass) {
this.glass = glass;
return this;
}
public Builder setLamp(String lamp) {
this.lamp = lamp;
return this;
}
public Car build() {
return new Car(this);
}
}
}
4、观察者模式
//抽象观察者
public interface Observer {
public void update(String message);
}
//具体观察者
public class Specific implements Observer {
private String name;
public Specific(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + "-" + message);
}
}
//抽象被观察者
public interface Subject {
/**
* 增加订阅者
* @param observer
*/
public void add(Observer observer);
/**
* 删除订阅者
* @param observer
*/
public void delete(Observer observer);
/**
* 通知订阅者更新消息
*/
public void notify(String message);
}
//具体被观察者
public class SubscriptionSubject implements Subject {
//储存订阅公众号的微信用户
private List<Observer> specificlist = new ArrayList<Observer>();
@Override
public void add(Observer observer) {
specificlist.add(observer);
}
@Override
public void delete(Observer observer) {
specificlist.remove(observer);
}
@Override
public void notify(String message) {
for (Observer observer : specificlist) {
observer.update(message);
}
}
}
5、适配器模式
class ABank {
public void aSave(){
System.out.println("aSave");
}
}
interface Target {
public void save();
}
class Adapter extends ABank implements Target {
@Override
public void save() {
super.aSave();
}
}
6、代理模式
- 静态代理 :
interface IUserDao {
void save();
}
class UserDao implements IUserDao {
public void save() {
System.out.println("----已经保存数据!----");
}
}
class UserDaoProxy implements IUserDao{
private IUserDao userDao;
public UserDaoProxy(IUserDao userDao){
this.userDao=userDao;
}
public void save() {
System.out.println("开始事务...");
userDao.save();//执行目标对象的方法
System.out.println("提交事务...");
}
public static void main(String[] args) {
//目标对象
UserDao target = new UserDao();
//代理对象,把目标对象传给代理对象,建立代理关系
UserDaoProxy proxy = new UserDaoProxy(target);
//执行的是代理的方法
proxy.save();
}
}
- 动态代理 :
- jdk动态代理
class DynamicProxy implements InvocationHandler {
private Object proxyObject;
public Object newProxyInstance(Object ProxyObject) {
this.proxyObject = ProxyObject;
return Proxy.newProxyInstance(ProxyObject.getClass().getClassLoader(), ProxyObject.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置方法");
Object result = null;
// 通过Java反射机制调用目标对象方法
result = method.invoke(proxyObject, args);
return result;
}
}
interface Act {
public void go();
}
class DailyAct implements Act {
@Override
public void go() {
System.out.println("去吃饭");
}
public static void main(String[] args) {
// 1. 创建调用处理器类对象
DynamicProxy DynamicProxy = new DynamicProxy();
// 2. 创建目标对象对象
DailyAct dailyAct = new DailyAct();
// 3. 创建动态代理类 & 对象:通过调用处理器类对象newProxyInstance()
// 传入上述目标对象对象
Act dynamicProxy = (Act) DynamicProxy.newProxyInstance(dailyAct);
dynamicProxy.go();
}
}
- cglib动态代理
class DynamicProxy implements MethodInterceptor {
/**
* 获取代理对象,这里的参数是Class类型
* 为啥是class类型,因为这里接收的参数是父类的class,我们需要继承这个父类
* 重写方法生成新的类
*/
public Object getInstance(Class clazz) {
//创建Enhancer对象,类似于JDK动态代理的Proxy类,下一步就是设置几个参数
Enhancer enhancer = new Enhancer();
//设置目标类
enhancer.setSuperclass(clazz);
// 设置拦截器,也就是这个类(CglibMeipoProxy)的intercept方法
enhancer.setCallback(this);
// 生成代理类并返回一个实例
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
// 调用被代理方法,注意这里是方法调用并不是用反射
Object result = methodProxy.invokeSuper(o, objects);
after();
return result;
}
/**
* 前置方法
*/
public void before(){
System.out.println("前置方法");
}
/**
* 后置方法
*/
public void after(){
System.out.println("后置方法");
}
}
interface Act {
public void go();
}
class DailyAct implements Act {
@Override
public void go() {
System.out.println("去吃饭");
}
public static void main(String[] args) {
// 1. 创建调用处理器类对象
DynamicProxy DynamicProxy = new DynamicProxy();
// 2. 创建目标对象对象
DailyAct dailyAct = new DailyAct();
// 3. 创建动态代理类 & 对象:通过调用处理器类对象newProxyInstance()
// 传入上述目标对象对象
Act dynamicProxy = (Act) DynamicProxy.getInstance(DailyAct.class);
dynamicProxy.go();
}
}
7、装饰模式
interface Coffee {
public void add();
}
class IceCoffee implements Coffee {
@Override
public void add() {
System.out.println("一杯咖啡,加冰块");
}
}
abstract class Decorator implements Coffee {
private Coffee coffee;
public void setcoffee(Coffee coffee) {
this.coffee = coffee;
}
@Override
public void add() {
System.out.println("公共处理流程");
coffee.add();
}
}
class MilkDecorator extends Decorator {
@Override
public void add() {
super.add();
addMilk();
}
public void addMilk() {
System.out.println("加奶");
}
public static void main(String[] args) {
IceCoffee iceCoffee = new IceCoffee();
MilkDecorator m = new MilkDecorator();
m.setcoffee(iceCoffee);
m.add();
}
}
8、策略模式
// 策略抽象类,超市促销策略
abstract class Strategy {
public abstract void calculate();
}
class StrategyA extends Strategy{
//策略A,满减的计算方式
@Override
public void calculate() {
System.out.println("策略A");
}
}
class StrategyB extends Strategy{
//策略B,优惠卷的计算方式
@Override
public void calculate() {
System.out.println("策略B");
}
}
class Context {
private Strategy strategy;
public void setStrategy(String stra) {
switch (stra) {
case "A":
strategy = new StrategyA();
break;
case "B":
strategy = new StrategyB();
break;
default:
strategy = null;
}
}
//获取计算方式计算
public void getResult(){
strategy.calculate();
}
}
9、模板模式
public abstract class AbstractAct {
/**
* 定义一个模板方法,用于实现这个方法的基本“骨架”
* 每一步骤的具体实现由子类完成
*/
public void day(){
walk();
byCar();
work();
}
public abstract void walk();
public abstract void byCar();
public abstract void work();
}
public class Ming extends AbstractAct {
@Override
public void walk() {
System.out.println("小明不走路");
}
@Override
public void byCar() {
System.out.println("小明开奥迪");
}
@Override
public void work() {
System.out.println("小明在办公室上班");
}
}
public class Chen extends AbstractAct {
@Override
public void walk() {
System.out.println("陈每天都散步");
}
@Override
public void byCar() {
//System.out.println();
}
@Override
public void work() {
System.out.println("陈在商场上班");
}
}