一、设计模式的目的
为了提升代码的重用性、可读性、扩展性、可靠性,从而使模块和模块之间出现高内聚低耦合。
二、七大设计原则
- 单一职责原则:简单来说就是 一个类应该只负责一项职责从而降低类的复杂度,例如:在学生类里不要做和食物类相关的事情,又或者常见的DAO。
- 接口隔离原则:一个类对另一个类的依赖应该建立在最小接口上。当类实现接口,这个接口应该遵循最小接口原则,无关的方法不需要实现,类中实现的都是需要的方法。
- 依赖颠倒原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象,其核心的面向接口编程。
public class DependecyInversion { public static void main(String[] args) { Person person = new Person(); person.getMessage(new Email()); person.getMessage(new Message()); } } // 将两个东西共同的地方抽象成一个接口,细节在各自类中具体实现,接口和抽象类的目的是制定好规范 interface IReceiver{ public void getInfo(); } class Email implements IReceiver{ @Override public void getInfo() { System.out.println("Email Received"); } } class Message implements IReceiver{ @Override public void getInfo() { System.out.println("Message Received"); } } class Person{ // 通过接口传递实现依赖,变量的类型尽量是抽象类或者接口 public void getMessage(IReceiver iReceiver){ iReceiver.getInfo(); } }
- 里氏替换原则:即子类尽量不要去重写父类的方法。继承实际上是让两个类之间的耦合性变强了。如果两个类没有符合里氏替换原则,可以将原来的父类和子类都继承一个更为通俗的类,改变原来的继承关系(也可以不改变),从而尽量使用基类。
class God{ public void func1(int a, int b){ System.out.println("GOD"); } } class Father extends God{ public void selfPrintByFather(int a, int b){ System.out.println("father"); } } class Son extends God{ public void selfPrintBySon(int a, int b) { System.out.println("son"); } }
- 开闭原则:即扩展开放(对于提供方),修改关闭(对于使用方)。也就是说增加一个功能只需要在提供方进行功能的增加,在调用的地方不做修改,和有点依赖颠倒原则类似。编程中最基础最重要的设计原则。
- 迪米特里法则:又叫最少知道原则,减少类和类的耦合度。即一个类对自己依赖的类知道的越少越好,对于被依赖的类将逻辑封装在自己类中对外提供调用方法,换句话说:一个类里面不要出现陌生类(局部变量的类),而是都是直接朋友(成员变量类、返回值类、方法参数类 都为直接朋友)。
class School{ // 这里打印了学生的信息 但是学生类并不是直接朋友 所以通过调用的方式去进行 public void getStudentBytTeacher(Teacher teacher){ teacher.getAllStudent(); } } class Teacher{ List<Student> studentList = new ArrayList<>(); public void setStudent(Student student){ this.studentList.add(student); } public void getAllStudent(){ for(Student student: studentList){ System.out.println(student.name+"==="+student.sex); } } } class Student{ public String name; public String sex; }
- 合成复用法则:类和类之间尽量使用 合成 / 聚合 的方式,而不是继承。从而减小耦合程度。区分类和类之间是聚合还是组合 如果这个类不依赖其他类就能进行初始化则和其他类是聚合关系 否则就是组合关系
三、工厂设计模式
工厂模式的意义在于将实力换的代码提取出来,放到一个类中进行同一个的管理和维护,达到和主项目的结构关系。
1. 简单工厂模式:适用于产品稳定的情况。
interface Cook{
public void cooking();
}
class ChineseChef implements Cook{
@Override
public void cooking() {
System.out.println("chinese");
}
}
class WesternChef implements Cook{
@Override
public void cooking() {
System.out.println("western");
}
}
// 简单工厂
public Cook chooseCooker(String type){
if("ChineseChef".equals(type)){
return new ChineseChef();
}else if("WesternChef".equals(type)){
return new WesternChef();
}else {
return null;
}
}
2. 抽象工厂:是简单工厂和工厂方法的结合,将工厂抽象成为两层,一层是抽象工厂,一层是工厂类。
// 抽象工厂
interface Choose{
public Cook chooseCooker(String type);
}
// 工厂类
class Restaurant implements Choose{
@Override
public Cook chooseCooker(String type){
if("ChineseChef".equals(type)){
return new ChineseChef();
}else if("WesternChef".equals(type)){
return new WesternChef();
}else {
return null;
}
}
}
interface Cook{
public void cooking();
}
class ChineseChef implements Cook{
@Override
public void cooking() {
System.out.println("chinese");
}
}
class WesternChef implements Cook{
@Override
public void cooking() {
System.out.println("western");
}
}
四、建造者模式
建造者模式 又叫生成器模式,是一种对象构建模式,将复杂的对象创建抽象出来,不同实现方法可以构造出不同表现,用户无需知道具体细节。适用于创建不同产品流程相同具体细节不同的场景(适用于差异性不大的情况)。
其核心有四个角色:产品角色、抽象构造者、具体建造者、指挥者。
产品角色:就是要创建的对象。
@Data
public class Computer {
public String type;
public Integer price;
public Integer weight;
}
抽象构造者:定义创建对象的大体流程,不涉及具体创建
public abstract class ComputerBuilder {
Computer computer = new Computer();
public abstract void addBoard();
public abstract void addSystem();
public abstract void addSSD();
public Computer getComputer(){
return computer;
}
}
具体建造者:继承抽象构造者,实现流程的具体细节
public class AppleComputer extends ComputerBuilder{
@Override
public void addBoard() {
computer.setWeight(11);
}
@Override
public void addSystem() {
computer.setPrice(3000);
}
@Override
public void addSSD() {
computer.setType("APPLE");
}
}
public class HuaweiComputer extends ComputerBuilder{
@Override
public void addBoard() {
computer.setWeight(19);
}
@Override
public void addSystem() {
computer.setPrice(1000);
}
@Override
public void addSSD() {
computer.setType("HUAWEI");
}
}
指挥者:调用具体建造者角色以创建产品对象的各个部分。在调用创建对象的时候直接去调用指挥者即可。
public class ComputerDirector {
ComputerBuilder computerBuilder;
public ComputerDirector(ComputerBuilder computerBuilder){
this.computerBuilder = computerBuilder;
}
public Computer startBuild(){
computerBuilder.addBoard();
computerBuilder.addSSD();
computerBuilder.addSystem();
return computerBuilder.getComputer();
}
}