漫谈设计模式(三):桥接(Bridge)模式 —— 将类功能、结构两层次分离
1.前言
类主要有两个层次,一个是功能层次,另一个是实现层次。
功能层次,一般应用于当前类不能满足多样化的业务需求,让子类去继承(具体)父类,添加加一些父类中没有的功能(一般是增加新的方法),这就属于因增加新功能而产生的层次结构。
实现层次,一般常见于子类去继承抽象类或接口,将抽象类或接口中的抽象方法重写,抽象类(接口)只声明了方法,而具体任务的分担需要子类去分担。相当于,子类只是将父类宣传出的口号、吹出的牛逼给落实了,将分配的任务给真正去做了,但它并没有增加新功能,只是实现父类的抽象方法,这就是类的实现层次。
若这两个层次在同一个类中实现,这就会将两种层次结构混杂在一起,相互影响,耦合度高,不利后期拓展。桥接模式就是将这两种层次分开,分别在两个类中实现,某一个层次的修改不会影响到另一个层次的实现。
2.代码实现
1).先定义一普通的POJO实体类Product
import java.math.BigDecimal; import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString; @Setter
@Getter
@ToString
@NoArgsConstructor
public class Product {
private Integer id;//产品id
private String name;// 产品名
private String description;// 描述
private BigDecimal price;// 价格 public Product(String name) {
super();
this.name = name;
}
public Product(BigDecimal price) {
super();
this.price = price;
}
public Product(Integer id, String name, String description) {
super();
this.id = id;
this.name = name;
this.description = description;
}
public Product(Integer id, String name, String description, BigDecimal price) {
super();
this.id = id;
this.name = name;
this.description = description;
this.price = price;
}
}
2).定义一个操作实体类Product的Dao层接口。这个接口有基本的增删改查的抽象方法。
import java.util.List; public interface ProductDao {
int addProduct(Product product);
int deleteProduct(int productId);
int modifyProduct(Product product);
List<Product> findProducts(Product product);
}
3).增加实现
随着客户对数据库的需求的变化,整个软件生命周期后期可能不只使用一种数据库,可能要编写在不同数据库平台上进行数据持久化操作的ProductDao实现类
/**
* 在Oracle数据库的实现
* @author Administrator
*
*/
public class ProductDaoOrancleImpl implements ProductDao { @Override
public int addProduct(Product product) {
System.out.println("在Orancle数据库中保存了一个产品"+product);
return 1;
} @Override
public int deleteProduct(int productId) {
System.out.println("在Orancle数据库中删除了一个产品,其id为"+productId);
return 1;
} @Override
public int modifyProduct(Product product) {
System.out.println("在Orancle数据库中修改了一个产品,修改后为"+product);
return 1;
} @Override
public List<Product> findProducts(Product product) {
Product p1=new Product(1, "洗衣机", "好用便宜的洗衣机");
Product p2=new Product(2, "T恤", "透气清爽的T恤");
System.out.println("从Orancle数据库中查询出的产品有:{"+p1+"},{"+p2+"}");
return Arrays.asList(p1,p2);
} }
在Oracle数据库的实现
import java.util.Arrays;
import java.util.List;
/**
* 在mysql数据库的实现
* @author Administrator
*
*/
public class ProductDaoMysqlImpl implements ProductDao{ @Override
public int addProduct(Product product) {
System.out.println("在mysql数据库中保存了一个产品"+product);
return 1;
} @Override
public int deleteProduct(int productId) {
System.out.println("在mysql数据库中删除了一个产品,其id为"+productId);
return 1;
} @Override
public int modifyProduct(Product product) {
System.out.println("在mysql数据库中修改了一个产品,修改后为"+product);
return 1;
} @Override
public List<Product> findProducts(Product product) {
Product p1=new Product(1, "洗衣机", "好用便宜的洗衣机");
Product p2=new Product(2, "T恤", "透气清爽的T恤");
System.out.println("在mysql数据库中查询出的产品有:{"+p1+"},{"+p2+"}");
return Arrays.asList(p1,p2);
}
}
在mysql数据库的实现
4.编写一个实现桥接功能并抽象化的具体类
这个类的关键在于委托机制,委托成员变量productDao去完成实际业务处理。当然productDao一定是ProductDao接口的实现类的实例对象,因为接口不能实例化。这个成员变量productDao是完成桥接的关键,它将接口被实现的方法 和ProductDaoBridge的子类可能出现的拥有新功能的方法给连接在了一起。
import java.util.List; public class ProductDaoBridge {
//被final修饰,初始化后不能去引用其他ProductDao对象
protected final ProductDao productDao; public ProductDaoBridge(ProductDao productDao) {
super();
this.productDao = productDao;
} public int addProduct(Product product) { return productDao.addProduct(product);
} int deleteProduct(int productId) {
return productDao.deleteProduct(productId);
} int modifyProduct(Product product) {
return productDao.modifyProduct(product); }
List<Product> findProducts(Product product){
return productDao.findProducts(product);
}
}
5).增加功能
业务处理中频繁要先查数据再进行删除,在子类中可以新增一个方法,将查删操作一并处理。
import java.util.List; public class MultiProductDaoBridge extends ProductDaoBridge { public MultiProductDaoBridge(ProductDao productDao) {
super(productDao);
} /**
* 查出查询后,全部删除
*
* @param product 查询条件
*/
//final修饰防止被子类重写
public final int[] findProductThenDelete(Product product) {
List<Product> products = this.productDao.findProducts(product);
int[] delOks = new int[products.size()];
for (int i = 0; i < products.size(); i++) {
delOks[i] = productDao.deleteProduct(products.get(i).getId());
}
return delOks;
} }
漫谈设计模式(三):桥接(Bridge)模式 —— 将类功能、结构两层次分离的更多相关文章
- 设计模式初探-桥接(Bridge)模式
桥接(Bridge)模式,又称Handle/Body模式,属于对象结构型模式.用于将抽象部分与它的实现部分分离,使它们都可以独立地变化.比如常见的电脑窗口界面,不同的操作系统其窗口界面绘制的原理肯定不 ...
- Java 实现桥接(Bridge)模式
类图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamp3d21scDQ1Ng==/font/5a6L5L2T/fontsize/400/fill/I0 ...
- 设计模式C++描述----09.桥接(Bridge)模式
一. 举例 N年前: 计算机最先出来时,软件和硬件是一绑在一起的,比如IBM出了一台电脑,上面有一个定制的系统,假如叫 IBM_Win,这个IBM_Win系统当然不能在HP电脑上运行,同样HP出的HP ...
- java设计模式三种工厂模式简单介绍
一.简单工厂模式 概述:简单工厂模式的创建意图就是,把对类的创建初始化全都交给一个工厂来执行,而用户不需要去关心创建的过程是什么样的,只用告诉工厂我想要什么就行了.而这种方法的缺点也很明显,违背了设计 ...
- java设计模式---三种工厂模式
工厂模式提供创建对象的接口. 工厂模式分为三类:简单工厂模式(Simple Factory), 工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory).GOF在 ...
- java23种设计模式——三、工厂模式
源码在我的github和gitee中获取 工厂模式 工厂模式介绍 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在J ...
- Java设计模式---桥接Bridge模式
参考于 : 大话设计模式 马士兵设计模式视频 写在开头: 桥接模式主要用于一件事物分成了两个维度,进行排列组合,比如礼物,可以分成优雅的礼物(抽象),花(具体),排列组合优雅的花! 1.为什么使用桥接 ...
- 设计模式--桥接(Bridge)模式
1.概述: 桥接模式:把抽象和行为分离开来,中间需要某个介质来连接抽象化和行为化.此模式的概述听起来非常像适配器模式,不要搞混了,虽然都是借用中间介质,但意义不同.最典型的桥接模式就是:JDBC.通过 ...
- java设计模式---三种工厂模式之间的区别
简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...
随机推荐
- 浅谈Python 中 __getattr__与__getattribute__的区别
__getattr__与__getattribute__均是一般实例属性截取函数(generic instance attribute interception method),其中,__getatt ...
- Elasticsearch 过滤
章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...
- vue学习(二)Vue常用指令
2 Vue常用指令 1. vue的使用要从创建Vue对象开始 var vm = new Vue(); 2. 创建vue对象的时候,需要传递参数,是json对象,json对象对象必须至少有两个属性成员 ...
- EUI库 - 10 - 使用自定义组件
步骤 1 在根节点,添加一个自定义的命名空间 2 可以设置skinName 自定义组件规范 1 不复用的不要用自定义组件 2 属性必须要有默认值(赋值为null也可以),因为TS编译器会把没有默 ...
- UVA 10003 区间DP
这个题目蛮有新意的,一度导致我没看透他是区间DP 给一个0-L长度的木板,然后给N个数,表示0-L之间的某个刻度,最后要用刀把每个刻度都切一下 使其断开,然后每次分裂的cost是分裂前的木板的长度.求 ...
- JavaWeb之搭建自己的MVC框架(二)
1. 前言 在 JavaWeb之搭建自己的MVC框架(一) 中我们完成了URL到JAVA后台方法的最基本跳转.但是实际操作中会发现有一个不方便的地方,现在在com.mvc.controller包中只有 ...
- leetcode算法题121-123 --78 --python版本
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 实例输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数组上操作,不能 ...
- Bugku杂项(1—28)
1.签到题 只要关注公众号就可以得到 flag---开胃菜 2.这是一张单纯的图片 用Winhex打开,会发现最下面有一行编码: key{you are right} 是一串HTML编码,解密下就行了 ...
- .net APP接口
编写APP接口首先要搭建测试环境,在实际开发中APP对于大多数公司来说都是选择外包,并不是公司内部人员负责,遇到事情不可能时时进行沟通和交流,也不能写每一个接口都要双方及时确认.个人经历是双方确认AP ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习: DOM
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...