所谓的设计模式(Design Pattern)是前辈们在长期的开发与实战中总结出的经验,与通用的解决方案。好的设计模式,可以获得“三高”效果:高可用性、高维护性、高可靠性。
一、简介与作用
1、设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
可以简单理解为特定问题的固定解决方法,主要由GOF(Group of four)四人组成员编撰而成。
2、在GOF的《设计模式》书中描述了23 种设计模式。
(1)创建型设计模式 (5种):单例模式、原型模式、建造者模式、工厂方法模式、抽象工厂模式;
在软件设计中对象的创建和对象的使用是分开的,因为对象的创建会消耗掉系统的很多资源,所以会单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题;
(2)结构型设计模式 (7种):代理模式、适配器模式、桥接模式、装饰器模式、外观模式、组合模式、享元模式;
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
(3)行为型设计模式 (11种):解释器模式、访问者模式、中介者模式、备忘录模式;迭代器模式、状态模式、观察者模式;命令模式、责任链、模板模式、策略模式;
行为模式不仅描述对象或类的模式,还描述它们之间的通信模式;
3、使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、重用性。
二、 设计模式六大原则
1、开闭原则(Open Closed Principle, OCP)
软件实体如类、模块和函数应该对扩展开放,对修改关闭。
2、里式替换(Liskov Substitution Principle, LSP)
子类必须能够替换其基类而不会改变程序的行为。
3、单一职责(Single Responsibility Principle, SRP)
一个类只负责一项职责,通过控制类的粒度大小来降低类与类之间的耦合,提高内聚性。
4、接口隔离
客户端不应该依赖它不需要的接口。
5、依赖倒置(Dependence Inversion Principle, DIP)
高层模块不应该依赖低层模块,两者都应该依赖其抽象。
6、迪米特法则(Law of Demeter, LOD)
一个对象应该对其他对象保持最少的了解。
三、案例解析
1、创建型模式
(1)单例模式
饿汉子方式:
public class RoseOne {
// 用单例方式创建类的对象,保证在任何时候只能有一个对象,从而实现对象的全局调用
// 实现方式:将无参构造方法私有化,然后自定义一个方法去获取对象
private static RoseOne rose = new RoseOne();
private RoseOne() { }
// 直接返回对象,此单例为饿汉子方式
public static RoseOne getInstance() {
return rose;
}
public int getMax(int a, int b) {
int max = 0;
if (a >= b) {
max = a;
} else {
max = b;
}
return max;
}
}
懒汉子模式:
public class RoseTwo {
// 单例模式之懒汉模式,延迟创建,不管声明多少个对象,最后都指向同一个空间
private static RoseTwo instance;
// 不允许从外部new对象
private RoseTwo() {
}
// 判断后再创建对象,懒汉模式
public static RoseTwo getInstance() {
// 两层if判断确保对象已存在就不创建,没有
// 才创建
if (instance == null) {
// 加同步锁
synchronized (RoseTwo.class) {
if (instance == null) {
instance = new RoseTwo();
} // if1
}
} // if2
return instance;
}
// 检验单例
int sum = 0;
// 写一个方法,检验一下
public int sum(int n) {
for (int i = 0; i < n; i++) {
sum += n;
}
return sum;
}
public int getSum() {
return sum;
}
}
(2)工厂方法:发送信息为例
创建发送消息接口
public interface Sender {
public String send();
}
创建发邮件实现类
public class EmailSender implements Sender{
@Override
public String send() {
return "我要发邮件!";
}
}
创建发短信实现类
public class SmsSender implements Sender {
@Override
public String send() {
return "我要发短信!";
}
}
创建工厂类
public class SenderFactory {
public Sender getObject(String str) {
Sender s=null;
if (str.equals("email")) {
s= new EmailSender();
} else if (str.equals("sms")) {
s=new SmsSender();
}
return s;
}
}
2、结构型模式
(1)代理模式,在代理模式中,一个类代表另一个类的功能。
/**
* 创建代理人与被代理人要做的事,对应的接口
*/
public interface StarService {
void speak();
}
/**
* 创建明星服务类
*/
public class Star implements StarService{
@Override
public void speak() {
System.out.println("我是star!");
}
}
/**
* 创建经纪人服务类,代理明星做更多的事
*/
public class Broker implements StarService {
private StarService s;
public Broker(StarService s){//传明星子类对象
this.s=s;
}
@Override
public void speak() {
System.out.println("----代理管理财务----");
s.speak();
System.out.println("----代理谈业务----");
}
//做更多事情
}
/**
* 测试类:测试代理模式
*/
public class DemoMain2 {
public static void main(String[] args) {
//创建被代理对象
StarService star = new Star();
//创建代理对象
StarService ss = new Broker(star);
//调用方法,实现更多功能
ss.speak();
}//main
}
(2)适配器,以构建水果对象为例
声明两个接口
public interface Apple {//苹果接口
void isApple();
}
public interface Pear {//梨接口
void speak();
}
PearImpl实现类
public class PearImpl implements Pear{
@Override
public void speak() {
System.out.println("我是甜甜的梨哦!");
}
}
创建ObjectAdapter适配器类
public class ObjectAdapter implements Apple {
private Pear pear;
public ObjectAdapter(Pear pear) {
this.pear=pear;
}
@Override
public void isApple() {
pear.speak();
}
}
ClassAdapter继承梨并实现苹果接口
public class ClassAdapter extends PearImpl implements Apple {
@Override
public void isApple() {
//调用了梨的方法
speak();
}
}
3、行为型设计模式
(1)迭代器模式,用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
//创建迭代器接口
public interface Iterator {
boolean hasNext();
Object next();
}
//创建容器接口
public interface Container {
Iterator getIterator();
}
//创建容器实现类
public class NameRepository implements Container {
public String[] names = {"小美" , "小帅" ,"小明" , "小芳"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
if(index < names.length){
return true;
}
return false;
}
@Override
public Object next() {
if(this.hasNext()){
return names[index++];
}
return null;
}
}
}
//测试一下
public class IteratorPatternDemo {
public static void main(String[] args) {
NameRepository namesRepository = new NameRepository();
for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
String name = (String)iter.next();
System.out.println("姓名: " + name);
}
}
}
(2)中介者模式,这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。
创建ChatRoom中介类:
public class ChatRoom {//聊天室
public static void showMessage(User user, String message){
System.out.println(new Date().toString()
+"[" user.getName() +"]:" + message);
}
}
创建User类:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String name){
this.name = name;
}
public void sendMessage(String message){
ChatRoom.showMessage(this,message);
}
}
使用 User 对象来显示他们之间的通信:
public class MediatorPatternDemo {
public static void main(String[] args) {
User tom = new User("Tom");
User bean = new User("Bean");
tom.sendMessage("Hi!Bean!");
bean.sendMessage("Hello! Tom!");
}
}
测试一下:执行程序获取结果
Thu Jan 28 16:05:46 IST 2024 [Tom]: Hi! Bean!
Thu Jan 28 16:05:46 IST 2024 [bean] : Hello! Tom!
提示:面试常见问题,列举Spring框架中常见的设计模式。
工厂设计模式 : Spring使用工厂模式通过BeanFactory、ApplicationContext创建bean对象。
代理设计模式 : Spring AOP功能的实现。
单例设计模式 : Spring中的Bean默认都是单例的。
模板方法模式 : Spring中JdbcTemplate、hibernateTemplate 等以Template结尾的对数据库操作的类,它们就使用到了模板模式。
装饰器设计模式 : 项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
观察者模式: Spring事件驱动模型就是观察者模式很经典的应用。
适配器模式 :Spring AOP的增强或通知(Advice)使用到了适配器模式、spring MVC中也是用到了适配器模式来适配Controller。
更多精彩内容关注本站其他分享!!!