面向对象编程设计原则之控制反转

控制反转

情景

先看下面这样一个例子:

定义一个UserDao接口,用来获取用户数据

package com.ys.dao;

public interface UserDao {
    void getUser();
}

在写两个实现UserDao接口的类

UserDaoImpl.java

package com.ys.dao;

public class UserDaoimpl implements UserDao {

    @Override
    public void getUser() {
        System.out.println("获取用户的数据");
    }
}

UserDaoMySqlImpl.java

package com.ys.dao;

public class UserDaoMysqlImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("MySql获取用户数据");
    }
}

写调用dao层的service层

UserService.java

package com.ys.service;

public interface UserService {
    void getUser();
}

UserServiceImpl.java

package com.ys.service;

import com.ys.dao.UserDao;
import com.ys.dao.UserDaoimpl;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    @Override
    public void getUser() {
        userDao = new UserDaoimpl();
        userDao.getUser();
    }
}

测试

import com.ys.dao.UserDao;
import com.ys.dao.UserDaoMysqlImpl;
import com.ys.dao.UserDaoimpl;
import com.ys.service.UserService;
import com.ys.service.UserServiceImpl;
import org.junit.Test;

public class MyTest {
    @Test
    public void Test1() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.getUser();
    }
}

注意看上面的程序,我们在主函数中的service中只调用了UserDao接口其中一个实现类UserDaoImpl,当我们想再次调用UserDao接口的另一个实现类UserDaoMySqlImpl时,我们得改动UserServiceimpl的代码如下:

package com.ys.service;

import com.ys.dao.UserDao;
import com.ys.dao.UserDaoMysqlImpl;
import com.ys.dao.UserDaoimpl;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    @Override
    public void getUser() {
        userDao = new UserDaoMysqlImpl();
        userDao.getUser();
    }
}

以上的改动明显违背了开闭原则,当我们要扩展原有业务时,要在原有的程序中修改显然是可取的,这将是一项很大的工程量。那也没有更好的办法能在不改动原有业务的代码的情况下又可以扩展“新业务"呢?

我们尝试对UserServiceImpl做如下的改动,增加一个set方法,来接收传进来的一个UserDao接口的实现类

import com.ys.dao.UserDao;
import com.ys.dao.UserDaoMysqlImpl;
import com.ys.dao.UserDaoimpl;
import com.ys.service.UserService;
import com.ys.service.UserServiceImpl;
import org.junit.Test;

public class MyTest {
    @Test
    public void Test1() {
//        用户实际调用的是业务,Dao层不需要接触
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoMysqlImpl());
//        userService.setUserDao(new UserDaoimpl());
        userService.getUser();
    }
}

从上面的改动后的程序来看,即使我们更改使用不同的业务,那么我们也不用对原有的dao层,service层做改动,而是在主程序中被动接收一个参数,就可以很好完成扩展 ,这样也符合开闭原则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员-小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值