一、Single Responsibility Principle
1. 传统模式
一个类中的方法,具备了不同种类的错误的功能,违反了单一职责
package com. design. pattern. day01;
public class Demo01 {
public static void main ( String[ ] args) {
Vehicle plane = new Vehicle ( "飞机" ) ;
plane. run ( ) ;
Vehicle boot = new Vehicle ( "轮船" ) ;
boot. run ( ) ;
Vehicle bike = new Vehicle ( "自行车" ) ;
bike. run ( ) ;
}
}
class Vehicle {
private String name;
public Vehicle ( String name) {
this . name = name;
}
public void run ( ) {
System. out. println ( name + "在天上飞" ) ;
}
}
2. 基于类
每个类都负责该类中所有功能,如果需要在该类中添加对应的功能,不会影响其他类中,符合单一职责原则 当类中的方法较少的时候,创建多个类会增大虚拟机开销
package com. design. pattern. day01;
public class Demo02 {
public static void main ( String[ ] args) {
PlaneVehicle planeVehicle = new PlaneVehicle ( ) ;
planeVehicle. run ( ) ;
BikeVehicle bikeVehicle = new BikeVehicle ( ) ;
bikeVehicle. run ( ) ;
BootVehicle bootVehicle = new BootVehicle ( ) ;
bootVehicle. run ( ) ;
}
}
class PlaneVehicle {
private String name = "飞机" ;
public void run ( ) {
System. out. println ( name + "天上飞" ) ;
}
}
class BootVehicle {
private String name = "船" ;
public void run ( ) {
System. out. println ( name + "水里游" ) ;
}
}
class BikeVehicle {
private String name = "自行车" ;
public void run ( ) {
System. out. println ( name + "路上走" ) ;
}
}
3. 基于方法
当逻辑足够简单或者类中方法较少时,可以不在类上,而是在方法上遵循单一职责原则
package com. design. pattern. day01;
public class Demo01 {
public static void main ( String[ ] args) {
Vehicle plane = new Vehicle ( "飞机" ) ;
plane. fly ( ) ;
Vehicle boot = new Vehicle ( "轮船" ) ;
boot. swim ( ) ;
Vehicle bike = new Vehicle ( "自行车" ) ;
bike. walk ( ) ;
}
}
class Vehicle {
private String name;
public Vehicle ( String name) {
this . name = name;
}
public void fly ( ) {
System. out. println ( name + "在天上飞" ) ;
}
public void swim ( ) {
System. out. println ( name + "在水里游" ) ;
}
public void walk ( ) {
System. out. println ( name + "在路上走" ) ;
}
}
二、Interface Segregation Principle
一个类对另外一个类的依赖,应该建立在最小接口的原则上
1. 传统模式
package com. design. pattern. day01;
public class Demo03 {
public static void main ( String[ ] args) {
}
}
class SportStarManager {
private Star star;
public SportStarManager ( Star star) {
this . star = star;
}
public void dailyWork ( ) {
star. eat ( ) ;
star. sleep ( ) ;
star. drink ( ) ;
star. playBall ( ) ;
star. sing ( ) ;
}
}
class SingerStarManager {
private Star star;
public SingerStarManager ( Star star) {
this . star = star;
}
public void dailyWork ( ) {
star. drink ( ) ;
star. eat ( ) ;
star. sleep ( ) ;
star. sing ( ) ;
star. playBall ( ) ;
}
}
class SingerStar implements Star {
@Override
public void eat ( ) {
System. out. println ( "刘德华吃饭" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "刘德华睡觉" ) ;
}
@Override
public void drink ( ) {
System. out. println ( "刘德华喝水" ) ;
}
@Override
public void sing ( ) {
System. out. println ( "刘德华唱歌" ) ;
}
@Override
public void playBall ( ) {
System. out. println ( "刘德华能打球吗?" ) ;
}
}
class SportStar implements Star {
@Override
public void eat ( ) {
System. out. println ( "李宁吃饭" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "李宁睡觉" ) ;
}
@Override
public void drink ( ) {
System. out. println ( "李宁喝水" ) ;
}
@Override
public void sing ( ) {
System. out. println ( "李宁能唱歌吗?" ) ;
}
@Override
public void playBall ( ) {
System. out. println ( "李宁打球" ) ;
}
}
interface Star {
void eat ( ) ;
void sleep ( ) ;
void drink ( ) ;
void sing ( ) ;
void playBall ( ) ;
}
2. Interface Segregation Principle
不同功能类型的接口,应该将大接口拆开若干个小的接口 通过一个类来继承公共的接口和各自类型的接口
package com. design. pattern. day01;
public class Demo03 {
public static void main ( String[ ] args) {
}
}
class SportStarManager {
private SportStar sportStar;
public SportStarManager ( SportStar sportStar) {
this . sportStar = sportStar;
}
public void dailyWork ( ) {
sportStar. drink ( ) ;
sportStar. eat ( ) ;
sportStar. sleep ( ) ;
sportStar. playBall ( ) ;
}
}
class SingerStarManager {
private SingerStar singerStar;
public SingerStarManager ( SingerStar singerStar) {
this . singerStar = singerStar;
}
public void dailyWork ( ) {
singerStar. sing ( ) ;
singerStar. drink ( ) ;
singerStar. sleep ( ) ;
singerStar. eat ( ) ;
}
}
class SingerStar implements Star , SingerStartInter {
@Override
public void eat ( ) {
System. out. println ( "刘德华吃饭" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "刘德华睡觉" ) ;
}
@Override
public void drink ( ) {
System. out. println ( "刘德华喝水" ) ;
}
@Override
public void sing ( ) {
System. out. println ( "刘德华唱歌" ) ;
}
}
class SportStar implements Star , SportStarInter {
@Override
public void eat ( ) {
System. out. println ( "李宁吃饭" ) ;
}
@Override
public void sleep ( ) {
System. out. println ( "李宁睡觉" ) ;
}
@Override
public void drink ( ) {
System. out. println ( "李宁喝水" ) ;
}
@Override
public void playBall ( ) {
System. out. println ( "李宁打球" ) ;
}
}
interface SportStarInter {
void playBall ( ) ;
}
interface SingerStartInter {
void sing ( ) ;
}
interface Star {
void eat ( ) ;
void sleep ( ) ;
void drink ( ) ;
}
三、Dependence Inversion Principle
高层模块不应该依赖低层模块,二者都应该依赖抽象类 抽象不应该依赖细节,细节应该依赖抽象 中心思想:面向接口编程 抽象的(抽象类或接口)相比细节(实现类)要稳定 接口或者抽象类:提前指定好规范,不涉及具体操作,具体操作由实现类
1. 传统方式
package com. design. pattern. day01;
public class Demo04 {
}
class SendService {
public void sendEmail ( Email email) {
email. contactCustomer ( ) ;
}
public void sendPush ( Push push) {
push. contactCustomer ( ) ;
}
public void sendSms ( Sms sms) {
sms. contactCustomer ( ) ;
}
}
class Email {
public void contactCustomer ( ) {
System. out. println ( "email to contact customer" ) ;
}
}
class Push {
public void contactCustomer ( ) {
System. out. println ( "push to contact customer" ) ;
}
}
class Sms {
public void contactCustomer ( ) {
System. out. println ( "sms to contact customer" ) ;
}
}
2. 改进方式
package com. design. pattern. day01;
public class Demo04 {
}
class SendService {
public void sendEmail ( Email email) {
email. contactCustomer ( ) ;
}
public void sendPush ( Push push) {
push. contactCustomer ( ) ;
}
public void sendSms ( Sms sms) {
sms. contactCustomer ( ) ;
}
}
class Email {
public void contactCustomer ( ) {
System. out. println ( "email to contact customer" ) ;
}
}
class Push {
public void contactCustomer ( ) {
System. out. println ( "push to contact customer" ) ;
}
}
class Sms {
public void contactCustomer ( ) {
System. out. println ( "sms to contact customer" ) ;
}
}
3. 依赖注入方式
依赖倒置原则(Dependency Inversion Principle)提供了降低模块间耦合度的一种思路 依赖注入(Dependency Injection)是一种具体的实施方法
3.1 接口参数传递
public class Demo04 {
public static void main ( String[ ] args) {
new SendService ( ) . send ( new Sms ( ) ) ;
new SendService ( ) . send ( new Email ( ) ) ;
new SendService ( ) . send ( new Push ( ) ) ;
new SendService ( ) . send ( ( ) - > System. out. println ( "other way to contact customer" ) ) ;
}
}
class SendService {
public void send ( CommunicateTools tool) {
tool. contactCustomer ( ) ;
}
}
3.2 构造器
class SendService {
private CommunicateTools tool;
public SendService ( CommunicateTools tool) {
this . tool = tool;
}
public void send ( ) {
tool. contactCustomer ( ) ;
}
}
3.3 setter方法
public class Demo04 {
public static void main ( String[ ] args) {
SendService pushService = new SendService ( ) ;
pushService. setTool ( new Push ( ) ) ;
pushService. send ( ) ;
SendService emailService = new SendService ( ) ;
emailService. setTool ( new Email ( ) ) ;
pushService. send ( ) ;
SendService smsService = new SendService ( ) ;
smsService. setTool ( new Sms ( ) ) ;
pushService. send ( ) ;
SendService other = new SendService ( ) ;
other. setTool ( ( ) - > System. out. println ( "其他方式联系客户" ) ) ;
other. send ( ) ;
}
}
class SendService {
private CommunicateTools tool;
public void setTool ( CommunicateTools tool) {
this . tool = tool;
}
public void send ( ) {
tool. contactCustomer ( ) ;
}
}
四、Liskov Substitution Principle
使用基类的地方,必须能够透明的使用子类 方式:子类中尽量不要重写父类的方法 继承时,子类无意识的重写父类方法,使得继承体系脆弱,一般是将两个类的公共部分抽取成更高层,然后让这两个类通过聚合,组合等实现
1. 子类重写父类
package com. day. dreamer. seven. liskvo;
public class TraditionalLiskvo {
public static void main ( String[ ] args) {
Animal animal = new Animal ( ) ;
animal. eat ( ) ;
Cat cat = new Cat ( ) ;
cat. eat ( ) ;
}
}
class Animal {
public void eat ( ) {
System. out. println ( "动物吃食物" ) ;
}
}
class Cat extends Animal {
public void eat ( ) {
System. out. println ( "猫吃鱼" ) ;
}
}
2. Extract改进
package com. day. dreamer. seven. liskvo;
public class ImprovedLiskvo {
public static void main ( String[ ] args) {
Cycle cycle = new Cycle ( ) ;
cycle. function ( ) ;
Bicycle bicycle = new Bicycle ( cycle) ;
bicycle. function ( ) ;
}
}
class Base {
public void work ( ) {
System. out. println ( "测试方法" ) ;
}
}
class Cycle extends Base {
public void function ( ) {
System. out. println ( "交通工具:正常使用" ) ;
}
}
class Bicycle extends Base {
private Cycle cycle;
public Bicycle ( Cycle cycle) {
this . cycle = cycle;
}
public void function ( ) {
cycle. function ( ) ;
System. out. println ( "自行车:正常使用" ) ;
}
}
五、Open Close Principle
一个类/方法,对修改关闭(consumer),对扩展(provider)开放。抽象搭建架构,实现做具体事情 对provider而言,新的功能,最好通过扩展而不是修改的方式实现,这样就不需要测试之前代码 其他所有设计原则,设计模式,最终就是要达到开放扩展模式 说白了:面向接口编程
1. 传统方式
package com. design. pattern. day01;
public class Demo06 {
public static void main ( String[ ] args) {
DrawShape tool = new DrawShape ( ) ;
tool. drawShape ( new Square ( ) ) ;
tool. drawShape ( new Triangle ( ) ) ;
}
}
class DrawShape {
public void drawShape ( Shape shape) {
if ( shape. type == 1 ) {
drawSquare ( ) ;
} else if ( shape. type == 2 ) {
drawTriangle ( ) ;
}
}
public void drawSquare ( ) {
System. out. println ( "画正方形" ) ;
}
public void drawTriangle ( ) {
System. out. println ( "画三角形" ) ;
}
}
class Square extends Shape {
private int squareType = 1 ;
public Square ( ) {
super . type = squareType;
}
}
class Triangle extends Shape {
private int triangleType = 2 ;
public Triangle ( ) {
super . type = triangleType;
}
}
class Shape {
public int type;
}
2. 改进-基于接口
package com. design. pattern. day01;
public class Demo06 {
public static void main ( String[ ] args) {
DrawShape tool = new DrawShape ( ) ;
tool. drawShape ( new Triangle ( ) ) ;
tool. drawShape ( new Square ( ) ) ;
tool. drawShape ( new Shape ( ) {
@Override
public void draw ( ) {
System. out. println ( "画其他图形" ) ;
}
} ) ;
}
}
class DrawShape {
public void drawShape ( Shape shape) {
shape. draw ( ) ;
}
}
class Square implements Shape {
@Override
public void draw ( ) {
System. out. println ( "画正方形" ) ;
}
}
class Triangle implements Shape {
@Override
public void draw ( ) {
System. out. println ( "画三角形" ) ;
}
}
interface Shape {
void draw ( ) ;
}
六、Demeter Principle
一个对象应该对其他对象保持最少的了解 一个类应该尽可能对外少暴露信息 陌生的类,应该通过成员变量,方法参数,方法返回值,而不是局部变量出现在当前类中
七、Composite Reuse Principle