type
status
date
slug
summary
tags
category
icon
password
一、设计模式的规范
设计模式遵循六⼤原则;单⼀职责( ⼀个类和⽅法只做⼀件事 )、⾥⽒替换( 多态,⼦类可扩展⽗类 )、依赖
倒置( 细节依赖抽象,下层依赖上层 )、接⼝隔离( 建⽴单⼀接⼝ )、迪⽶特原则( 最少知道,降低耦合 )、开闭
原则( 抽象架构,扩展实现 ),会在具体的设计模式章节中,进⾏体现。
二、依赖倒置原则
定义:程序依赖接口,接口定义标准和规范,具体的实现按照场景,而不是使用对象硬编码的方式实现

三、示例
模拟场景:
1、例如:领导有事需要开部门例会,领导是不可能去每个工位,喊各位同事去参加会议。领导只会在工作群里面申明,今天什么时间段开会,各位收到消息后,自行去开会。。。
2:例如:用户抽奖有随机抽奖和权重抽奖两种方式,我们只需要定义出一套抽奖抽象标准。具体的实现,看随机和权重的不同实现。
非依赖倒置原则(硬编码)
投注用户:
BetUser
package com.qf.principle.dependenceinverse.tradition; /** * @description 投注用户 */ public class BetUser { private String userName; // 用户姓名 private int userWeight; // 用户权重 public BetUser() { } public BetUser(String userName, int userWeight) { this.userName = userName; this.userWeight = userWeight; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getUserWeight() { return userWeight; } public void setUserWeight(int userWeight) { this.userWeight = userWeight; } }
抽奖控制,硬编码里面的实现方式:
DrawControl
package com.qf.principle.dependenceinverse.tradition; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * @description 抽奖控制 */ public class DrawControl { // 随机抽取指定数量的用户,作为中奖用户 public List<BetUser> doDrawRandom(List<BetUser> list, int count) { // 集合数量很小直接返回 if (list.size() <= count) return list; // 乱序集合 Collections.shuffle(list); // 取出指定数量的中奖用户 List<BetUser> prizeList = new ArrayList<>(count); for (int i = 0; i < count; i++) { prizeList.add(list.get(i)); } return prizeList; } // 权重排名获取指定数量的用户,作为中奖用户 public List<BetUser> doDrawWeight(List<BetUser> list, int count) { // 按照权重排序 list.sort((o1, o2) -> { int e = o2.getUserWeight() - o1.getUserWeight(); if (0 == e) return 0; return e > 0 ? 1 : -1; }); // 取出指定数量的中奖用户 List<BetUser> prizeList = new ArrayList<>(count); for (int i = 0; i < count; i++) { prizeList.add(list.get(i)); } return prizeList; } }
测试:
ApiTest
package com.qf.principle.dependenceinverse.tradition; import com.alibaba.fastjson.JSON; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; public class ApiTest { private Logger logger = LoggerFactory.getLogger(ApiTest.class); @Test public void test_DrawControl(){ List<BetUser> betUserList = new ArrayList<>(); betUserList.add(new BetUser("花花", 65)); betUserList.add(new BetUser("豆豆", 43)); betUserList.add(new BetUser("小白", 72)); betUserList.add(new BetUser("笨笨", 89)); betUserList.add(new BetUser("丑蛋", 10)); DrawControl drawControl = new DrawControl(); List<BetUser> prizeRandomUserList = drawControl.doDrawRandom(betUserList, 3); logger.info("随机抽奖,中奖用户名单:{}", JSON.toJSON(prizeRandomUserList)); List<BetUser> prizeWeightUserList = drawControl.doDrawWeight(betUserList, 3); logger.info("权重抽奖,中奖用户名单:{}", JSON.toJSON(prizeWeightUserList)); } }
依赖倒置原则
投注用户:
BetUser
package com.qf.principle.dependenceinverse.design; /** * @description 投注用户 */ public class BetUser { private String userName; // 用户姓名 private int userWeight; // 用户权重 public BetUser() { } public BetUser(String userName, int userWeight) { this.userName = userName; this.userWeight = userWeight; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getUserWeight() { return userWeight; } public void setUserWeight(int userWeight) { this.userWeight = userWeight; } }
定义接口抽奖:
IDraw
package com.qf.principle.dependenceinverse.design; import java.util.List; public interface IDraw { List<BetUser> prize(List<BetUser> list, int count); }
随机抽奖实现:
RandomDraw
package com.qf.principle.dependenceinverse.design; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class RandomDraw implements IDraw{ // 随机抽取指定数量的用户,作为中奖用户 @Override public List<BetUser> prize(List<BetUser> list, int count) { // 集合数量很小直接返回 if (list.size() <= count) return list; // 乱序集合 Collections.shuffle(list); // 取出指定数量的中奖用户 List<BetUser> prizeList = new ArrayList<>(count); for (int i = 0; i < count; i++) { prizeList.add(list.get(i)); } return prizeList; } }
权重抽奖实现:
WeightDraw
package com.qf.principle.dependenceinverse.design; import java.util.ArrayList; import java.util.List; public class WeightDraw implements IDraw { // 权重排名获取指定数量的用户,作为中奖用户 @Override public List<BetUser> prize(List<BetUser> list, int count) { // 按照权重排序 list.sort((o1, o2) -> { int e = o2.getUserWeight() - o1.getUserWeight(); if (0 == e) return 0; return e > 0 ? 1 : -1; }); // 取出指定数量的中奖用户 List<BetUser> prizeList = new ArrayList<>(count); for (int i = 0; i < count; i++) { prizeList.add(list.get(i)); } return prizeList; } }
抽奖控制:
DrawControl
package com.qf.principle.dependenceinverse.design; import java.util.List; /** * @description 抽奖控制 */ public class DrawControl { private IDraw draw; public List<BetUser> doDraw(IDraw draw,List<BetUser> list, int count){ return draw.prize(list,count); } }
测试:
ApiTest
package com.qf.principle.dependenceinverse.design; import com.alibaba.fastjson.JSON; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; public class ApiTest { private Logger logger = LoggerFactory.getLogger(com.qf.principle.dependenceinverse.tradition.ApiTest.class); @Test public void test_DrawControl(){ List<BetUser> betUserList = new ArrayList<>(); betUserList.add(new BetUser("花花", 65)); betUserList.add(new BetUser("豆豆", 43)); betUserList.add(new BetUser("小白", 72)); betUserList.add(new BetUser("笨笨", 89)); betUserList.add(new BetUser("丑蛋", 10)); DrawControl drawControl = new DrawControl(); List<BetUser> prizeRandomUserList=drawControl.doDraw(new RandomDraw(),betUserList,3); logger.info("随机抽奖,中奖用户名单:{}", JSON.toJSON(prizeRandomUserList)); List<BetUser> prizeWeightUserList=drawControl.doDraw(new WeightDraw(),betUserList,3); logger.info("权重抽奖,中奖用户名单:{}", JSON.toJSON(prizeWeightUserList)); } }
UML关系图
硬编码的方式:具体的实现都在此类里

依赖倒置方式:

总结:
依赖倒置原则增加了代码的可维护性,利用多态的特性,上级只需要定义标准,下级负责实现,跟装饰者模式有点类似
- 作者:程序员小舟
- 链接:https://codezhou.top/article/JAVA%E3%80%90%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%91%E4%BE%9D%E8%B5%96%E5%80%92%E7%BD%AE%E5%8E%9F%E5%88%99
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章