栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式 依赖倒置原则

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式 依赖倒置原则

文章目录

依赖倒置原则依赖倒置原则实战

使用依赖倒置原则进行改变案例中两种方式的类图

依赖倒置原则

定义:
程序要依赖于抽象接口, 不要依赖于具体实现, 对抽象进行编程, 而不是对实现进行编程, 降低了客户与实现模块的耦合.
高层模块不应该依赖底层模块, 都应该依赖抽象(接口 抽象类)

上级找下级, 一般不会直接找你 ,而是通过助理等找到.
下级去依赖上级的标准等. 上级出的标准, 不需要去关心下级如何去实现的. 降低上级的耦合性.
spring的spi机制等.

依赖倒置原则实战

随机抽奖与权重抽奖.
不使用依赖倒置原则的写法 :
定义抽奖用户类

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;
    }
}

抽奖控制类, 在抽奖控制类中, 分别实现了随机抽奖, 和根据权重排序抽奖的方法.

public class DrawControl {
    
    
    public List doDrawRandom(List list, int count) {
        if (list.size() <= count) {
            return list;
        }
        // 集合乱序
        Collections.shuffle(list);

        // 取出指定数量的中奖用户
        List prizeList = new ArrayList();
        for (int i = 0; i < count; i++) {
            prizeList.add(list.get(i));
        }
        return prizeList;
    }
    
    public List doDrawWeight(List list, int count) {
        //按权重排序
        list.sort((o1, o2) -> {
            int e = o2.getUserWeight() - o1.getUserWeight();
            if (e == 0) {
                return 0;
            }
            return e > 0 ? 1 : -1;
        });
        // 取出指定数量的中奖用户
        List prizeList = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            prizeList.add(list.get(i));
        }
        return prizeList;
    }
}

测试类

public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_DrawControl() {
        List 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 prizeRandomUserList = drawControl.doDrawRandom(betUserList, 3);
        logger.info("随机抽奖, 中奖用户:{}", JSON.toJSON(prizeRandomUserList));

        List prizeWeightUserList = drawControl.doDrawWeight(betUserList, 3);
        logger.info("权重抽奖, 中奖用户名单:{}", JSON.toJSON(prizeWeightUserList));
    }
}

控制台打印如下 :

随机抽奖, 中奖用户:[{“userWeight”:10,“userName”:“丑蛋”},{“userWeight”:65,“userName”:“花花”},{“userWeight”:43,“userName”:“豆豆”}]
权重抽奖, 中奖用户名单:[{“userWeight”:89,“userName”:“笨笨”},{“userWeight”:72,“userName”:“小白”},{“userWeight”:65,“userName”:“花花”}]

使用依赖倒置原则进行改变

抽奖用户类与上面一致, 定义一个抽奖的接口

public interface IDraw {

    
    List prize(List list, int count);
}

分别创建随机抽奖类和权重抽奖类, 实现抽奖接口

public class DrawRandom implements IDraw{

    @Override
    public List prize(List list, int count) {
        if (list.size() <= count) {
            return list;
        }
        // 集合乱序
        Collections.shuffle(list);

        // 取出指定数量的中奖用户
        List prizeList = new ArrayList();
        for (int i = 0; i < count; i++) {
            prizeList.add(list.get(i));
        }
        return prizeList;
    }
}

public class DrawWeightRank implements IDraw {

    @Override
    public List prize(List list, int count) {
        //按权重排序
        list.sort((o1, o2) -> {
            int e = o2.getUserWeight() - o1.getUserWeight();
            if (e == 0) {
                return 0;
            }
            return e > 0 ? 1 : -1;
        });
        // 取出指定数量的中奖用户
        List prizeList = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            prizeList.add(list.get(i));
        }
        return prizeList;
    }
}

创建抽奖控制类, 方法入参含有抽奖的接口

public class DrawControl {

    public List doDraw(IDraw draw, List betUserList, int count) {
        return draw.prize(betUserList, count);
    }
}

测试类. drawControl.doDraw 方法中分别new 随机抽奖和权重抽奖.

public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_DrawControl() {
        List 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 prizeRandomUserList = drawControl.doDraw(new DrawRandom(), betUserList, 3);
        logger.info("随机抽奖, 中奖用户名单:{}", JSON.toJSON(prizeRandomUserList));

        List prizeWeightUserList = drawControl.doDraw(new DrawWeightRank(), betUserList, 3);
        logger.info("权重抽奖, 中奖用户名单:{}", JSON.toJSON(prizeWeightUserList));
    }
}

控制台打印如下

随机抽奖, 中奖用户名单:[{“userWeight”:72,“userName”:“小白”},{“userWeight”:10,“userName”:“丑蛋”},{“userWeight”:43,“userName”:“豆豆”}]
权重抽奖, 中奖用户名单:[{“userWeight”:89,“userName”:“笨笨”},{“userWeight”:72,“userName”:“小白”},{“userWeight”:65,“userName”:“花花”}]

案例中两种方式的类图

未使用依赖倒置时, 抽奖控制类直接实现两种不同的抽奖方法

使用依赖倒置, 抽奖控制类只需传递抽奖控制的接口, 无需知道底层实现.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/762808.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号