一.设计原则
Java的23种设计模式是根据设计原则来的,设计原则实际模式的设计依据.
每一个类用来处理一类事物,尽量使用接口进行方法规范(少使用继承),类与类之间尽量使用引用关系。
- 单一原则:一个类只处理一类事物(分为类单一和方法单一)
A.类单一

讯享网
B.方法单一
- 接口隔离原则
一个类如果只需要一个接口中的部分方法,请将该接口进行分离.一个接口用来处理一类事物

隔离原则应当这样处理:
将接口 Interface1拆分为独立的几个接口(这里我们拆分成 3 个接口),类 A 和类 C 分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则( 每一个类所依赖的接口为最小接口,最小接口就是接口中的规定的方法不要有多余的)
- 依赖倒转原则
依赖倒转原则是指:
(1)高层模块不应该依赖低层模块,二者都应该依赖其抽象
(2)抽象不应该依赖细节,细节应该依赖抽象
(3)依赖倒转(倒置)的中心思想是面向接口编程,使用多态(父类引用指向子类对象)
(4)依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java 中,抽象指的是接口或抽象类,细节就是具体的实现类
(5)使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成
- 里氏替换原则
- 在继承的时候,子类无意间重写父类的方法。如果我们对父类中的方法进行了修改,有可能会影响到子类的代码。
- 继承在给程序设计带来便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。
- 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法
- 里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖 来解决问题。
- 开闭原则
- 对扩展开放,对修改关闭 .是对父类开放扩展,对子类关闭修改(不要试图修改子类的方式来修改父类)
- 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
- 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。

- 迪米特法则:对外暴露越少越好,类与类之间尽量找直接关系。
(1)迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外泄露任何信息
(2)迪米特法则还有个更简单的定义:只与直接的朋友通信
- 合成复用原则
- 就是尽量使用类与类的引用关系来进行方法的调用
例一
例二
合成复用其实就是做类与类的引用
二.设计模式
设计模式是根据设计原则结合实际开发中的方式,进行总结出来的一套编程模式。 根据需求不同分类 :
创建型模式: 主要是用来实例化对象用的 (单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式)
结构型模式: 对象或类的调用(适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式)
行为型模式: 不同类之间的相互处理(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter 模式)、状态模式、策略模式、职责链模式(责任链模式))
- 单例模式
- 通过类new一次就会得到一个实例对象,多次new得到是不同的对象。
- 如果需要得到同一个对象:单例模式是通过改变获取java对象的方式得到同一个java对象 (不要使用new的方式来得到java对象) 使用方
- 为了不让使用方直接使用:将提供方的构造方法私有化
//构造方法 private Student(String name){
this.name=name; } private Student(){
}
讯享网
操作是对构造方法私有化,封装的思想,暴露一个得到java的public方法
单例模式就是为了得到相同的对象,不使用new的方式来得到对象(使用方),在本类中将构造方法进行私有化,提供一个返回一个java对象的public方法。那个使用方要一个java对象 就使用我的公共方法得到。
(1)饿汉模式: 管你有没有 我都要创建
- 使用静态属性来统一java对象

- 使用静态代码块的方式来得到对象

饿汉模式会导致内存浪费,没有要实例化对象的时候,对象都已经被实例化出来了 。
(2) 懒汉模式
得到对象的时候,第一次进来,如果对象没有被实例化,我们就实例化一个,如果已经实例化了,就直接拿来用就可以了。

- 工厂模式
- 所谓的工厂就是一个第三方类,工具类。
测试类–>工厂–>Student
(1) 普通工厂

(2)静态工厂
就是我只需要通过工厂的流水线得到我要的实例化对象,我并不需要工厂对象。

(3) 抽象工厂
- 该工厂是一个抽象的, 该工厂自己不会干,找两个实际工厂来做(多态思想 )
- 抽象工厂自己并不会生产,拥有的是抽象方法,实际根据需要使用多态得到已知实现子类工厂。 实际调用的是非抽象工厂的方法来创建手机对象。
可以将工厂升级为接口来实现
作用:对代码的修改维护降低

- 代理工厂
- 使用第三方代理对象类调用要代理的对象,执行代理对象的方法其实就是执行被代理对象的方法。(代理对象,被代理对象)
- 作用:是用来对被代理对象的方法进行增强
- 手动编写的代理程序 、 JDK动态代理、CGLib动态代理
代理模式注意以下几点:
- 代理对象的方法与被代理对象的方法声明的时候一致(返回值、参数、方法名)
- 实际使用的时候调用的是代理对象的方法,其实最终调用的就是被代理对象的方法
- 在代理对象中,调用被代理对象的方法时候对方法进行增强(扩展)不能减弱。
- 代理在日常开发中的主要功能:日志记录,异常信息输出
- 五种增强方式:前置,后置,环绕,最终,异常

- 建造者模式(Service三层架构: 控制层,业务层,实际操作层)
将实例化对象的方式分为了不同的操作
(1)建造者模式的四个角色
- Product(产品角色): 一个具体的产品对象。
- Builder(抽象建造者): 创建一个 Product 对象的各个部件指定的 接口/抽象类。
- ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。
- Director(指挥者): 构建一个使用 Builder 接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
- Javabean实体类:不应该有该类的操作
- 建造者:操作该Javabean的接口或者抽象类(方法只有定义没有具体执行 )
- 具体建造者(具体的执行者):操作类/接口 实现类
- 指挥者:Service 控制层,业务层,实际操作层
- 主启动类:不与核心对象有直接关系 ,通过指挥者来建立联系
eg:
学生管理系统 数组
StudentBean 实体类
StudentDao 接口
StudentDaoImp 实际操作者
StudentService 指挥者(调用实际操作做)
StudentTest 主程序 (测试类)
Student类(实体类)
讯享网public class Student {
private String name; private int age; public String getName() {
return name; } public void setName(String name) {
this.name = name; } public int getAge() {
return age; } public void setAge(int age) {
this.age = age; } public Student(String name, int age) {
super(); this.name = name; this.age = age; } public Student() {
super(); // TODO Auto-generated constructor stub } @Override public String toString() {
return "Student [name=" + name + ", age=" + age + "]"; } }
StudentDao类(接口)
public interface StudentDao {
// 查询所有 去数组中查 Student[] getAllStudent(Student[] students); }
StudentDaoImp类
讯享网public class StudentDaoImp implements StudentDao {
@Override public Student[] getAllStudent(Student[] students) {
Student[] stus=new Student[students.length]; int index=0; // 查询有效数据 for (Student student : students) {
if(student!=null) {
stus[index]=student; System.out.println(student);// 输出语句 index++; } } return stus; } }
StudentService类
public class StudentService {
// 引用接口,合成复用原则 private StudentDao studentDao; //引用 //构造方法 public StudentService() {
super(); // TODO Auto-generated constructor stub } public StudentService(StudentDao studentDao) {
super(); this.studentDao = studentDao; } // 业务层调用实际操作层 public Student[] getAllStudent(Student[] students) {
// 实际是使用实际操作类来查询 Student[] allStudent = studentDao.getAllStudent(students); return allStudent; } }
StudentTest类(测试类)
讯享网public class StudentTest {
public static void main(String[] args) {
// 容器 Student [] students=new Student[3]; students[0]=new Student("张三",20); students[1]=new Student("张三001",21); students[2]=new Student("张三002",22); // 实例化 业务层 需要一个接口对象,使用多态用已知实现子类来做 StudentService ss= new StudentService(new StudentDaoImp()); // 调用 业务层代码 ss.getAllStudent(students); } }
- 建造者模式必须遵守四个对象 实体、接口、实现类、业务类。
- 代码的扩展和维护方便,接口清楚,对于操作的约束性很高。
- 适配器模式:将不符合要求的东西转为符合要求的东西
(1)适配器模式基本介绍
适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表 示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,其别名为包装器(Wrapper)
适配器模式属于结构型模式
主要分为三类:类适配器模式、对象适配器模式、接口适配器模式
(2)适配器模式工作原理
适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容
从用户的角度看不到被适配者,是解耦的
用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法
用户收到反馈结果,感觉只是和目标接口交互
a.类适配器模式
Dian220类
public class Dian220 {
public int outV() {
return 200; } }
Dian5类
讯享网public class Dian5 {
// 充电 public void chongdian() {
Dian220 d220=new Dian220(); int outV = d220.outV(); // 转换 if(outV==5) {
System.out.println("直接充电"); }else {
// 对现有电压进行转换 outV=5; if(outV==5) {
System.out.println("转换后 可以充电了"); }else {
System.out.println("电压不对不能充电"); } } } }
测试类
public class ShiTest {
@Test void test() {
Dian5 d5=new Dian5(); d5.chongdian(); } }
b.对象适配器
(1) 思路和类的适配器模式相同,只是将 Adapter 类作修改,不是继承 src 类,而是持有 src 类的实例,以解决兼容性的问题。 即:持有 src 类,实现 dst 类接口,完成 src->dst 的适配
(2)根据“合成复用原则”,在系统中尽量使用关联关系(聚合)来替代继承关系。
(3)对象适配器模式是适配器模式常用的一种
- 使用合成复用原则,将继承去掉,使用类与类的引用。
- 一个类无法直接使用另外一个类提供的方法,需要一个第三方类来我们将原本不合适的方法进行转换,达到正常使用的效果




版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/116927.html