设计原则(单一原则,接口隔离原则,依赖倒转原则...)和设计模式(单例模式,工厂模式...)

一.设计原则

Java的23种设计模式是根据设计原则来的,设计原则实际模式的设计依据.

每一个类用来处理一类事物,尽量使用接口进行方法规范(少使用继承),类与类之间尽量使用引用关系。

  1. 单一原则:一个类只处理一类事物(分为类单一和方法单一)
    A.类单一
    在这里插入图片描述
    B.方法单一
    在这里插入图片描述

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

在这里插入图片描述
隔离原则应当这样处理:
将接口 Interface1拆分为独立的几个接口(这里我们拆分成 3 个接口),类 A 和类 C 分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则( 每一个类所依赖的接口为最小接口,最小接口就是接口中的规定的方法不要有多余的)

  1. 依赖倒转原则

依赖倒转原则是指:

(1)高层模块不应该依赖低层模块,二者都应该依赖其抽象

(2)抽象不应该依赖细节,细节应该依赖抽象

(3)依赖倒转(倒置)的中心思想是面向接口编程,使用多态(父类引用指向子类对象)

(4)依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java 中,抽象指的是接口或抽象类,细节就是具体的实现类

(5)使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

  1. 里氏替换原则
  • 在继承的时候,子类无意间重写父类的方法。如果我们对父类中的方法进行了修改,有可能会影响到子类的代码。
  • 继承在给程序设计带来便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。
  • 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法
  • 里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖 来解决问题。
  1. 开闭原则
  • 对扩展开放,对修改关闭 .是对父类开放扩展,对子类关闭修改(不要试图修改子类的方式来修改父类)
  • 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
  • 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。

在这里插入图片描述

  1. 迪米特法则:对外暴露越少越好,类与类之间尽量找直接关系。

(1)迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外泄露任何信息

(2)迪米特法则还有个更简单的定义:只与直接的朋友通信

  1. 合成复用原则
  • 就是尽量使用类与类的引用关系来进行方法的调用

例一在这里插入图片描述
例二在这里插入图片描述

合成复用其实就是做类与类的引用

二.设计模式

设计模式是根据设计原则结合实际开发中的方式,进行总结出来的一套编程模式。 根据需求不同分类 :
创建型模式: 主要是用来实例化对象用的 (单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式)
结构型模式: 对象或类的调用(适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式)
行为型模式: 不同类之间的相互处理(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter 模式)、状态模式、策略模式、职责链模式(责任链模式))

  1. 单例模式
  • 通过类new一次就会得到一个实例对象,多次new得到是不同的对象。

  • 如果需要得到同一个对象:单例模式是通过改变获取java对象的方式得到同一个java对象 (不要使用new的方式来得到java对象) 使用方

  • 为了不让使用方直接使用:将提供方的构造方法私有化

//构造方法
private Student(String name){
	this.name=name;
	}
private Student(){
}

操作是对构造方法私有化,封装的思想,暴露一个得到java的public方法
单例模式就是为了得到相同的对象,不使用new的方式来得到对象(使用方),在本类中将构造方法进行私有化,提供一个返回一个java对象的public方法。那个使用方要一个java对象 就使用我的公共方法得到。
(1)饿汉模式: 管你有没有 我都要创建

  • 使用静态属性来统一java对象
    在这里插入图片描述

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

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

  1. 工厂模式
  • 所谓的工厂就是一个第三方类,工具类。

测试类–>工厂–>Student
(1) 普通工厂
在这里插入图片描述

(2)静态工厂
就是我只需要通过工厂的流水线得到我要的实例化对象,我并不需要工厂对象。
在这里插入图片描述

(3) 抽象工厂

  • 该工厂是一个抽象的, 该工厂自己不会干,找两个实际工厂来做(多态思想 )
  • 抽象工厂自己并不会生产,拥有的是抽象方法,实际根据需要使用多态得到已知实现子类工厂。 实际调用的是非抽象工厂的方法来创建手机对象。
    可以将工厂升级为接口来实现
    作用:对代码的修改维护降低
    在这里插入图片描述
  1. 代理工厂
  • 使用第三方代理对象类调用要代理的对象,执行代理对象的方法其实就是执行被代理对象的方法。(代理对象,被代理对象)
  • 作用:是用来对被代理对象的方法进行增强
  • 手动编写的代理程序 、 JDK动态代理、CGLib动态代理

代理模式注意以下几点:

  • 代理对象的方法与被代理对象的方法声明的时候一致(返回值、参数、方法名)
  • 实际使用的时候调用的是代理对象的方法,其实最终调用的就是被代理对象的方法
  • 在代理对象中,调用被代理对象的方法时候对方法进行增强(扩展)不能减弱。
  • 代理在日常开发中的主要功能:日志记录,异常信息输出
  • 五种增强方式:前置,后置,环绕,最终,异常
    在这里插入图片描述
  1. 建造者模式(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. 适配器模式:将不符合要求的东西转为符合要求的东西
    (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)对象适配器模式是适配器模式常用的一种

  • 使用合成复用原则,将继承去掉,使用类与类的引用。
  • 一个类无法直接使用另外一个类提供的方法,需要一个第三方类来我们将原本不合适的方法进行转换,达到正常使用的效果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值