[19/04/26-星期五] GOF23_结构型模式(桥接模式、组合模式)
一、桥接模式(bridge)
场景:商城系统中常见的商品分类,以电脑为例,首先想到使用多层继承结构。
—— 台式机(联想台式机、戴尔台式机、神舟台式机)
电脑 ——笔记本(联想笔记本、戴尔笔记本、神舟笔记本)
——平板电脑(联想pad、戴尔pad、神舟pad)
问题:(1)如果要增加一个新的电脑类型,则要增加各个品牌下的类。
(2)如果要增加一个新的品牌,也要增加各种电脑类型的类
把另一个类的结构作为属性放在这个类中。
核心:处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联
好处:桥接模式可以取代多层继承的方案。 多层继承违背了单一职责原则,复用性较差,类的个数也非常多。桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本。
桥接模式极大的提高了系统可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有的系统,符合开闭原则。
应用场景:
– JDBC驱动程序
– AWT中的Peer架构
– 银行日志管理:
• 格式分类:操作日志、交易日志、异常日志
• 距离分类:本地记录日志、异地记录日志
– 人力资源系统中的奖金计算模块:
• 奖金分类:个人奖金、团体奖金、激励奖金。
• 部门分类:人事部门、销售部门、研发部门。
– OA系统中的消息处理:
• 业务类型:普通消息、加急消息、特急消息
• 发送消息方式:系统内消息、手机短信、邮件
【不用桥接模式UML类图】
【代码】
/***
* "电脑"接口 不用桥接模式
*/
package cn.sxt.bridge; public interface Computer {
void sale(); } class Desktop implements Computer{
public void sale() {
System.out.println("销售台式机!");
}
}
class Laptop implements Computer{
public void sale() {
System.out.println("销售笔记本!");
}
}
class Pad implements Computer{
public void sale() {
System.out.println("销售平板电脑!");
}
} //联想系列
class LenovoDesktop extends Desktop{
public void sale() {
System.out.println("销售联想台式机!");
}
}
class LenovoLaptop extends Laptop{
public void sale() {
System.out.println("销售联想笔记本!");
}
}
class LenovoPad extends Pad{
public void sale() {
System.out.println("销售联想平板!");
}
}
//神舟系列
class ShenZhouDesktop extends Desktop{
public void sale() {
System.out.println("销售神舟台式机!");
}
}
class ShenZhouLaptop extends Laptop{
public void sale() {
System.out.println("销售神舟笔记本!");
}
}
class ShenZhouPad extends Pad{
public void sale() {
System.out.println("销售神舟平板!");
}
} //戴尔系列
class DellDesktop extends Desktop{
public void sale() {
System.out.println("销售戴尔台式机!");
}
}
class DellLaptop extends Laptop{
public void sale() {
System.out.println("销售戴尔笔记本!");
}
}
class DellPad extends Pad{
public void sale() {
System.out.println("销售戴尔平板!");
}
}
【使用桥接模式UML类图】
【代码】
/***
* "品牌"接口 和各种具体品牌类,又一个维度,2个维度相互独立,x轴
*/
package cn.sxt.bridge; public interface Brand {
void sale();
} class Lenovo implements Brand{
@Override
public void sale() {
System.out.println("销售联想牌电脑");
}
} class Dell implements Brand{
@Override
public void sale() {
System.out.println("销售戴尔牌电脑");
}
}
//在这里,新加品牌“神舟”
class ShenZhou implements Brand{
@Override
public void sale() {
System.out.println("销售神舟牌电脑");
}
}
/**
* 电脑类型,一个维度,y轴
*/
package cn.sxt.bridge; public class Computer2 {
protected Brand brand;//持有Brand类的引用,使电脑类Computer2 天然具有品牌类(Brand)的属性 public Computer2(Brand b) {//构造器
this.brand=b;
} public void sale() {
brand.sale();//调用的是Brand类中brand对象的sale方法
}
} class Desktop2 extends Computer2{
public Desktop2 (Brand b) {
super(b);
}
public void sale() {
super.sale();
System.out.println("销售台式机");
}
}
class Laptop2 extends Computer2{
public Laptop2 (Brand b) {
super(b);
}
public void sale() {
super.sale();
System.out.println("销售笔记本");
}
}
【客户】
/***
* 客户端
*/
package cn.sxt.bridge; public class Client {
public static void main(String[] args) {
//销售联想牌的笔记本电脑,用组合来代替继承,后期扩展很方便
Computer2 c= new Laptop2(new Lenovo());
c.sale();
Computer2 c1= new Desktop2(new ShenZhou());
c1.sale();
} }
二、组合模式(Composite、复合物)
场景:把部分和整体的关系用树形结构来表示,从而使客户端可以用统一的方式处理部分对象和整体对象。
核心:
– 抽象构件(Component)角色: 定义了叶子和容器构件的共同点
– 叶子(Leaf)构件角色:无子节点,叶子节点。
– 容器(Composite)构件角色: 有容器特征,可以包含子节点。非叶子节点
组合模式工作流程分析:
– 组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。
– 当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。
开发中的应用场景:
– 操作系统的资源管理器
– GUI中的容器层次图
– XML文件解析
– OA系统中,组织结构的处理
– Junit单元测试框架:底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器)、Test接口(抽象)
【类图】
【概念】
/***
* 抽象组件,叶子节点和非叶节点的共同点。Component:组成部分、成分、部件
*/
package cn.sxt.composite; public interface Component {
void operation(); } //叶子组件节点
interface Leaf extends Component{ }
//容器组件,非叶节点
interface Composite extends Component{
void add (Component c);//增加节点
void remove(Component c);//删除节点
Component getChild(int index);//获得孩子节点 }
【叶子节点和非叶子节点】
/***
* 抽象文件(AbstractFile)接口,相当于Component接口(抽象组件)
*/
package cn.sxt.composite; import java.util.ArrayList;
import java.util.List; public interface AbstractFile {
void killVirus();
} class ImageFile implements AbstractFile{//相当于叶子节点Leaf,单个文本中不能再包含其他文件
private String name; public ImageFile(String name) {
this.name=name;
}
@Override
public void killVirus() {
System.out.println("查杀图片文件:"+name);
}
} class TextFile implements AbstractFile{
private String name; public TextFile(String name) {
this.name=name;
}
@Override
public void killVirus() {
System.out.println("查杀文本文件:"+name);
}
} class VideoFile implements AbstractFile{
private String name; public VideoFile(String name) {
this.name=name;
}
@Override
public void killVirus() {
System.out.println("查杀视频文件:"+name);
}
} class Folder implements AbstractFile{//Folder:文件夹 ,容器组件,非叶子节点
private String name;
//定义容器,用来存储子节点
private List<AbstractFile> list =new ArrayList<AbstractFile>(); public Folder(String name) {
this.name=name;
} public void add(AbstractFile file) {
list.add(file);
}
public void remove(AbstractFile file) {
list.remove(file);
}
public AbstractFile getChild(int index) {
return list.get(index);
} //杀毒
public void killVirus() {//递归:自己调用自己
System.out.println("对文件夹:"+name+",进行查杀。");
for (AbstractFile absFile : list) {
absFile.killVirus();
}
} }
【客户端】
/**
*
*/
package cn.sxt.composite; public class CLient {
public static void main(String[] args) {
AbstractFile f2,f3,f4,f5,f6;
Folder f1=new Folder("古装剧收藏");
f2=new ImageFile("SongYi.jpg");
f3=new TextFile("SheDiao.txt");
f4=new VideoFile("zhifou.mp4");
f2.killVirus(); f1.add(f2);
f1.add(f3);
f1.add(f4);
Folder f11=new Folder("胡歌的古装剧");
f5=new ImageFile("xianjian1.avi");
f6=new TextFile("Shenhua.mp4");
f11.add(f5);
f11.add(f6);
f1.add(f11);//文件夹套文件夹
f1.killVirus();//无论是文件f2还是文件夹f1都是继承同一个AbstractFile接口中的killVirus()方法,只调用这个方法即可 } }
[19/04/26-星期五] GOF23_结构型模式(桥接模式、组合模式)的更多相关文章
- [19/04/28-星期日] GOF23_结构型模式(享元模式)
一.享元模式(FlyWeight,轻量级) [共享类与非共享类] /*** *FlyweightFactory享元工厂类: 创建并管理享元对象,享元池一般设计成键值对 */ package cn.sx ...
- 设计模式-结构型模式,python组合模式
设计模式上大的方向上分继承和组合,就是类模式和对象模式.此篇的组合模式非继承和组合概念中的组合.桥接 策略 代理 装饰者都用了组合,此组合非彼组合. 组合模式 组合模式(Composite Patte ...
- NET设计模式 第二部分 结构性模式(10):组合模式(Composite Pattern)
组合模式(Composite Pattern) ——.NET设计模式系列之十一 Terrylee,2006年3月 概述 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复 ...
- 《JAVA与模式》之组合模式
定义(GoF<设计模式>): 将对象组合成树形结构以表示“部分整体”的层次结构.组合模式使得用户对单个对象和使用具有一致性. 及角色: 1.Component 是组合中的对象声明接口,在适 ...
- [19/04/27-星期六] GOF23_结构型模式(装饰模式、外观模式)
一.装饰模式(decorator) 职责:动态的为一个对象增加新的功能. 是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能.使用对象的关联关系代替继承关系,更加灵活,避免类体系的膨胀 ...
- [19/04/25-星期四] GOF23_结构型模式(适配器模式、代理模式)
一.引言 结构模式:核心作用就是从程序的结构上实现松耦合,从而扩大整体的类结构,用来解决更大的问题. 二.适配器模式(adapter) 生活中假设笔记本是标准的USB接口但是外置键盘是圆形接口,这时候 ...
- 结构型设计模式之享元模式(Flyweight)
结构 意图 运用共享技术有效地支持大量细粒度的对象. 适用性 一个应用程序使用了大量的对象. 完全由于使用大量的对象,造成很大的存储开销. 对象的大多数状态都可变为外部状态. 如果删除对象的外部状态, ...
- 【编程思想】【设计模式】【结构模式Structural】组合模式composite
Python版 https://github.com/faif/python-patterns/blob/master/structural/composite.py #!/usr/bin/env p ...
- 组合模式/composite模式/对象结构型模式
组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...
随机推荐
- SQL 之开启远程访问
转载自 http://blog.csdn.net/happymagic/article/details/51835522 SQL Server 开启远程访问的方法: 注意事项:(重点) 此次演示版本 ...
- 个人所得税计算java版
年关将至,该到了发年终奖的时候了.所以就到网上去找下,个税计算器,但是发现做的有点像病毒网站似的.所以计算结果也不太敢信,于是琢磨着,要不自己动手写一个个税计算器吧. 说干就干,先上国家税务局了解了下 ...
- 搭建 Visual Studio 2012 + DXperience-13.2.6 + MySql 开发平台
一. 开发环境 1. 此开发平台主要用来开发基于.NET 4.0及以上版本的应用 2. 点击此下载 Visual Studio 2012 Ultimate 中文版开发工具 3. 点击此下载 DXper ...
- php之连接mssql(sql server)新手教程
ps:网上搜了很多教程,讲的都很好,就是都有点漏的地方,花了一天时间查缺补漏终于弄好了(;´༎ຶД༎ຶ`),希望我的教程能帮到新手,还有写博客的时候因为不小心按错一个键,导致重写了,博客园这个编辑器真 ...
- 域模型中的实体类分为四种类型:VO、DTO、DO、PO
经常会接触到VO,DO,DTO的概念,本文从领域建模中的实体划分和项目中的实际应用情况两个角度,对这几个概念进行简析. 得出的主要结论是:在项目应用中,VO对应于页面上需要显示的数据(表单),DO对应 ...
- 【vue】混合模式
因为工作的分配,写财务的对账部分,因为3个页面的设计和功能基本相同,都是查询筛选表格,所以用混合模式优化了部分代码.用混合把一些共用的东西抽离了出来. 具体使用方法参照文档. https://cn.v ...
- Linux(Ubuntu16.04)下添加新用户
某些情况下,Ubuntu 使用useradd 新用户名,在home 文件夹下面看不到新创建的用户文件夹,例如: 发现找不到,spark的文件夹,因此将采用下面方式重新建立首先删除spark用户 若想给 ...
- php中http_build_query函数
http_build_query ( array $formdata [, string $numeric_prefix ] ) 使用给出的关联(或下标)数组生成一个经过 URL-encode 的请求 ...
- flask多线程多协程操作
local的作用:各个线程各开辟一块空间互不影响 基于local""" import threading from threading import local impo ...
- spring boot(3)-Rest风格接口
Rest接口 虽然现在还有很多人在用jsp,但是其实这种动态页面早已过时,现在前端流行的是静态HTML+ rest接口(json格式).当然,如果是单台服务器,用动态还是静态页面可能没什么很大区别,但 ...