设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术方案总结构成设计模式,也会使其他开发者更加容易理解其设计思路。设计模式是可复用的面向对象软件的基础,帮助开发者做出有利于系统复用的选择,避免损害系统复用性的设计。
面向对象原则
- 单一职责原则
单一职责规定一个类应该有且仅有一个引起它变化的原因,简单来说,一个类应该只负责一个职责;否则,类应该被拆分。
该原则提出一个类不应该承担太多职责。如果一个类承担了太多职责,字少存在以下两个缺点。
- 一个职责的变化可能会影响这个类实现其他职责的能力,或者引发其他职责故障。
- 当客户需要该类的某一个职责时,不得不将其他不需要的职责全部包含进来,从面造成冗余或风险。
- 开闭原则
在程序需要精选拓展的时候,不能通过修改已有的代码实现变化,而应该通过扩展软件实体的方式实现,如根据需求重新派生一个实现类。
- 里氏替换原则
任何基类可以出现的地方,子类一定可以出现。里氏代换原则是继承复用的基石,只有当衍生类可以替换基类,软件单位的功能不受影响时,基类才能真正的被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
- 依赖倒置原则
依赖倒转原则是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
- 接口隔离原则
客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。
- 迪米特法则
迪米特法则又叫做最少知识原则,就是说一个对象应当对其它对象又尽可能少的了解,不和陌生人说话。
- 合成复用原则
合成复用原则要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。如果要使用继承关系,则必须严格遵循里氏替换原则。合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。
一、设计模式的应用
简单工厂模式示例
package com.bdqn.factory;
import com.bdqn.dao.NewsDao;
import com.bdqn.dao.NumberDao;
import com.bdqn.dao.impl.*;
public class SimpleDaoFactory {
public static NewsDao getInstance(){
return new NewsDaoImpl();
}
public static NewsDao getInstance(String key){
// return new NewsDaoImpl();
switch (key){
case "mysql":
return new NewsDaoMySqlImpl();
case "oracle":
return new NewsDaoOracleImpl();
case "redis":
return new NewsDaoRedisImpl();
default: throw new RuntimeException("无效的数据库类型:"+key+", Dao获取失败");
}
}
public static NumberDao getCount(String str){
switch (str){
case "+":
return new AddDaoImpl();
case "-":
return new MinusDaoImpl();
case "*":
return new RideDaoImpl();
case "/":
return new DividedDaoImpl();
default:throw new RuntimeException("输入错误!");
}
}
}
与简单工厂类耦合
package com.bdqn.service.Impl;
import com.bdqn.dao.News;
import com.bdqn.dao.NewsDao;
import com.bdqn.dao.impl.NewsDaoImpl;
import com.bdqn.service.NewsService;
public class NewsServiceImpl implements NewsService {
NewsDao newsDao = new NewsDaoImpl();
// private NewsDao dao = (NewsDao) SimpleDateFormat.getInstance();
private NewsDao dao;
public void setDao(NewsDao dao) {
this.dao = dao;
}
public void addNews(News news){
dao.save(news);
}
@Override
public void save(News news) {
dao.save(news);
}
}
测试代码
import com.bdqn.dao.News;
import com.bdqn.dao.NewsDao;
import com.bdqn.factory.SimpleDaoFactory;
import com.bdqn.service.Impl.NewsServiceImpl;
import org.junit.jupiter.api.Test;
public class NewsServiceImplTest {
@Test
public void addNews() throws Exception {
NewsDao dao = SimpleDaoFactory.getInstance("mysql");
// NewsDao dao = SimpleDaoFactory.getInstance();
NewsServiceImpl service = new NewsServiceImpl();
service.setDao(dao);
News news = new News();
news.setNtitle("测试标题2");
news.setNcontent("测试内容2");
service.addNews(news);
}
}
从以上示例可以看出,简单工厂模式包含以下角色:
- 工厂(Factory)
- 抽象产品(Product)
- 具体产品(Concrete product)