设计模式全详解

您所在的位置:网站首页 手机工程模式有哪些类型 设计模式全详解

设计模式全详解

2024-07-16 01:38| 来源: 网络整理| 查看: 265

本文是学习设计模式后,自己做的笔记。

学习资源有菜鸟教程以及尚硅谷韩顺平图解设计模式。

文章目录 1 适配器模式概述:特点:角色:类图:类适配器:步骤代码实现: 接口适配器:步骤代码实现: 对象适配器:步骤代码实现: 适配器模式的注意事项和细节 2 桥接模式概述:特点:角色:类图:步骤代码实现:优缺点分析: 3 装饰模式概述:角色:类图:步骤代码实现:优缺点分析: 4 组合模式概述:特点:角色:类图示例:步骤代码实现:组合模式的注意事项和细节 5 外观模式概述:特点:角色:步骤代码实现: 6 享元模式概述:特点:角色:类图实例:步骤代码实现:享元模式的注意事项和细节 7 代理模式概述:特点:角色:类图示例:静态代理:代码实现:动态代理:步骤代码实现: Chlib代理:步骤代码实现: 代理模式注意事项和小结

1 适配器模式 概述:

一种作为两个不兼容接口的桥梁的模式,结合两个独立接口的功能。

其思想类似于生活中的插口转换器。

适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)适配器模式属于结构型模式主要分为三类:类适配器模式、对象适配器模式、接口适配器模式 特点:

可以将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

角色:

1、被适配者

2、适配器(中间桥梁作用)

3、适配者

类图:

适配器模式类图

在适配器中持有某需要适配的对象,然后进行转换适配。 类适配器:

要继承适配类并且实现适配器接口。

会导致无法再继承其他类,限制了类的兼容。

步骤代码实现: 创建适配者 // 1、适配者 public class Voltage { public int ouput220v() { int src = 220; System.out.println(" 输出220V电压!"); return src; } } 创建适配器接口 //2、适配器接口 public interface Voltage5V { int output5v(); } 创建适配器对象(适配器对象需要间接拥有需要适配的对象) //3、适配器实现对象(继承与实现) public class VoltageAdapter extends Voltage implements Voltage5V{ @Override public int output5v() { int src = ouput220v(); int dstv = src/44; return dstv; } } 定义被适配对象 //4、定义被适配对象 public class Phone { public void charging(Voltage5V voltage5V ) { if(voltage5V.output5v()==5) { System.out.println("电压为5V可以充电!"); }else if(voltage5V.output5v()>5) { System.out.println("电压过高,不可充电!"); } } } 调用 // 5、客户端调用 public class client { public static void main(String[] args) { System.out.println("========类适配器模式=========="); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } } 接口适配器:

一些书籍称为:适配器模式(Default Adapter Pattern)或缺省适配器模式

设计一个抽象类实现接口,并为该接口所有方法提供一个默认实现,该抽象类所有子类可以有选择的覆盖父类的方法来实现功能。

核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。

适用于一个接口不想使用其所有的方法的情况。

步骤代码实现: 写一个接口 //1、写一个接口 public interface interface1 { void m1(); void m2(); void m3(); void m4(); }

2、写一个抽象类空实现所有方法

//2、写一个抽象类空实现所有方法 //空实现所有接口方法 public abstract class AbcAdapter implements interface1{ @Override public void m1() { // TODO Auto-generated method stub } @Override public void m2() { // TODO Auto-generated method stub } @Override public void m3() { // TODO Auto-generated method stub } @Override public void m4() { // TODO Auto-generated method stub } } 调用时有选择得进行复写 //3、调用时有选择得进行复写 public class Client { public static void main(String[] args) { AbcAdapter absadapter = new AbcAdapter() { public void m1() { System.out.println("调用m1!"); } }; absadapter.m1(); } } 对象适配器:

不在继承适配器类,而是持有适配器类,解决兼容性问题。满足合成复用原则,是常用得一种。

满足合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst必须是接口。

成本低,更灵活。

步骤代码实现: 创建适配者 // 1、适配者 public class Voltage { public int ouput220v() { int src = 220; System.out.println(" 输出220V电压!"); return src; } } 创建适配器接口 //2、适配器接口 public interface Voltage5V { int output5v(); } 创建适配器对象(在此处聚合一个适配者对象) //3、适配器对象(聚合一个适配者对象) public class VoltageAdapter implements Voltage5V{ private Voltage voltege220v; public VoltageAdapter(Voltage voltage220v) { this.voltege220v=voltage220v; } @Override public int output5v() { if(voltege220v != null) { int src = voltege220v.ouput220v(); int dstv = src/44; return dstv; }else { return 0; } } 定义被适配对象 } //4、定义被适配对象 public class Phone { public void charging(Voltage5V voltage5V ) { if(voltage5V.output5v()==5) { System.out.println("电压为5V可以充电!"); }else if(voltage5V.output5v()>5) { System.out.println("电压过高,不可充电!"); } } } 调用 // 5、客户端调用 public class client { public static void main(String[] args) { System.out.println("========对象适配器模式=========="); Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage())); } } 适配器模式的注意事项和细节 三种命名方式,是根据 src 是以怎样的形式给到 Adapter(在 Adapter 里的形式)来命名的。类适配器:以类给到,在 Adapter 里,就是将 src 当做类,继承 对象适配器:以对象给到,在 Adapter 里,将 src 作为一个对象,持有 接口适配器:以接口给到,在 Adapter 里,将 src 作为一个接口,实现Adapter 模式最大的作用还是将原本不兼容的接口融合在一起工作 2 桥接模式 概述:

一种将实现与抽象放在两个不同得类层次,使得两个类层次可以独立改变的设计模式。

特点:

把类的抽象跟行为分离开。保持各个部分的独立性以及他们的功能拓展。

基于类的最小设计原则,通过使用封装、聚合以及继承等行为让不同的类承担不同的责任。

用于两个层次的组合,可将类数由n*n变为n+n

角色:

1、抽象类(聚合接口以及定义抽象)

2、接口

3、接口实现类

4、抽象类实现类

5、具体调用端

类图:

桥接模式类类图

在phone这一抽象类中队brand和继承者进行组合,对于类的多种组合的类数量可以由阶层关系转为相加关系。 步骤代码实现:

实现手机样式跟手机品牌的组合

定义行为接口 //1、定义行为接口 public interface Interface { void open(); void close(); void call(); } 实现行为接口 //2、行为接口的实现 public class Xiaomi implements Interface { @Override public void open() { // TODO Auto-generated method stub System.out.println(" 小米手机开机!"); } @Override public void close() { // TODO Auto-generated method stub System.out.println(" 小米手机关机!"); } @Override public void call() { // TODO Auto-generated method stub System.out.println(" 小米手机打电话!"); } } public class Vivo implements Interface{ @Override public void open() { // TODO Auto-generated method stub System.out.println(" Vivo手机开机!"); } @Override public void close() { // TODO Auto-generated method stub System.out.println(" Vivo手机关机!"); } @Override public void call() { // TODO Auto-generated method stub System.out.println(" Vivo手机打电话!"); } } 定义桥接类抽象

可以由代码看出,此处的接口实现选取与抽象行为的实现是独立的,可以自由的选择进行组合。

//3、抽象类的定义(桥接类) //桥接类,把实现的接口和抽象进行分离 public abstract class Phone { Interface brand; //聚合接口 public Phone(Interface brand) { this.brand = brand; } //抽象行为 protected void open() { brand.open(); } protected void close() { brand.close(); } protected void call() { brand.call(); } }

4、桥接类的实现

此处进行具体的组合

//4、桥接类的实现 public class FoldPhone extends Phone{ public FoldPhone(Interface brand) { //使用父类的构建方法 super(brand); } //抽象子类进行具体的层次组合 public void open() { super.open(); System.out.println(" 折叠手机样式手机"); } public void close() { super.close(); System.out.println(" 折叠手机样式手机"); } public void call() { super.call(); System.out.println(" 折叠手机样式手机"); } } 调用 //5、使用 public class Client { public static void main(String[] args) { FoldPhone foldPhone = new FoldPhone(new Vivo()); foldPhone.call(); foldPhone.close(); foldPhone.open(); } } 优缺点分析:

优点:

1、抽象和实现的分离。 (接口与抽象行为分离)

2、优秀的扩展能力。

3、实现细节对客户透明。

4、替代多层继承,减少类个数

缺点:

1、桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。

2、桥接模式要求分析出系统两个层次,即两个独立变化的维度。(此例中的手机品牌和手机样式)

3 装饰模式 概述:

是一种允许向一个现有的对象添加新的功能,同时又不改变其结构的设计模式。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

动态的将新功能附加在对象上,在对象扩展上比继承更有弹性,装饰者模式体现了开闭原则。

核心想实现的功能是动态的装饰一个类,给类动态的增加新功能而不使用大量的子类。

角色:

1、抽象构件(Component)角色:给出一个抽象接口,以规范准备接受附加责任的对象。

2、具体构件(ConCreteComponent)角色:定义一个将要接受附加责任的类。

3、装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

4、具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

类图:

装饰者模式类图 图中的左边是产品,右边是装饰类,在装饰类中持有产品示例,对产品进行装饰后返回装饰完的产品。

步骤代码实现:

实现咖啡点餐与加入调料

创建抽象产品类 //1、创建抽象产品类 public abstract class Drink { public String des; //描述。 private float price = 0.0f; public String getDes() { return des; } public void setDes(String des) { this.des = des; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public abstract float cost(); } 创建产品实体类(用于缓冲) //2、创建实体类实现抽象类(用于缓冲) public class Coffee extends Drink{ @Override public float cost() { return super.getPrice(); } } 创建各种实体类 //3、各种实体类 public class ShortBlack extends Coffee{ public ShortBlack() { setDes(" shortblack"); setPrice(4.0f); } } public class LongBlack extends Coffee{ public LongBlack() { setDes(" longblack"); setPrice(5.0f); } } public class Espresso extends Coffee{ public Espresso() { setDes("意大利咖啡"); setPrice(6.0f); } } 创建装饰者类(内部聚合产品类以及继承产品类,继承用于调用产品类元素,聚合用于包装某个产品类) //4、创建装饰者类(内部聚合产品类以及继承产品类,继承用于调用产品类元素,聚合用于包装某个产品类) public class Decorator extends Drink{ Drink obj; //内部再聚合一个Drink,被装饰 public Decorator(Drink obj) { this.obj = obj; } @Override public float cost() { return super.getPrice() + obj.getPrice(); //聚合类的价格加上一次继承下来的价格(也就是装饰类中定义的价格),类似递归获取,然后保存在属性中。 } @Override public String getDes() { //obj.getDes()输出被装饰者的类 return des + " " + getPrice() + "&&" + obj.getDes(); } } 继承实现装饰类 //5、继承实现装饰类 public class Milk extends Decorator{ public Milk(Drink obj) { super(obj); setDes(" 牛奶"); setPrice(2.0f); } } public class Soy extends Decorator{ public Soy(Drink obj) { super(obj); setDes(" 豆浆"); setPrice(1.5f); } } public class Chocolate extends Decorator{ public Chocolate(Drink obj) { super(obj); setDes(" 巧克力"); setPrice(3.0f); } } 调用 //6、具体调用 public class Client { public static void main(String[] args) { Drink order = new LongBlack(); System.out.println("费用1:" + order.cost()); System.out.println("描述:" + order.getDes()); order = new Milk(order); //传入被装饰 System.out.println("加入一份牛奶费用:" + order.cost()); System.out.println("加入一份牛奶描述:" + order.getDes()); } } 优缺点分析:

优点:

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:

多层装饰比较复杂。系统复杂性上升。

4 组合模式 概述:

组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。

一种依据树形结构来组合对象,用来表示部分以及整体层次的设计模式。

组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。

也就是说去除了层次等级关系,由用户自己定义对象之间的关系。

特点:

它创建了对象组的树形结构。

把有等级层次的对象划分成统一层次的对象,并在同一层次中进行树状的构建(对象内部聚合对象list)。

将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

角色:

1、抽象构成者

2、实体构成者(内部相互聚合形成树状结构)

类图示例:

组合模式类图

看与看出来,各个类之间(部门、学院、学校)去除了等级关系,由他们进行组合来形成自定义的等级关系。

步骤代码实现:

目标:实现学校部门专业遍历,构建同层次的树状结构。

创建抽象构成者 //1、创建抽象构成者 public abstract class OrganizationComponent { private String name; //名字 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDes() { return des; } public void setDes(String des) { this.des = des; } private String des; //说明 //空实现方法供子类选择 protected void add(OrganizationComponent organizationcomponent) { throw new UnsupportedOperationException(); } protected void remove(OrganizationComponent organizationcomponent) { throw new UnsupportedOperationException(); } public OrganizationComponent(String name,String des) { super(); this.name = name; this.des = des; } protected abstract void print(); } 创建构成类实例: //2、实例构成类 public class University extends OrganizationComponent { ArrayList organizationcomponents =new ArrayList(); //用list来储存分支,形成树状 public University(String name, String des) { super(name, des); } protected void add(OrganizationComponent organizationcomponent) { organizationcomponents.add(organizationcomponent); } protected void remove(OrganizationComponent organizationcomponent) { organizationcomponents.remove(organizationcomponent); } public String getName() { return super.getName(); } public String getDes() { return super.getDes(); } //遍历输出 protected void print() { System.out.println("---------------"+getName()+"----------------"); for(OrganizationComponent organizationcomponent:organizationcomponents) { organizationcomponent.print(); } } } public class College extends OrganizationComponent{ public College(String name, String des) { super(name, des); // TODO Auto-generated constructor stub } ArrayList organizationcomponents =new ArrayList(); protected void add(OrganizationComponent organizationcomponent) { organizationcomponents.add(organizationcomponent); } protected void remove(OrganizationComponent organizationcomponent) { organizationcomponents.remove(organizationcomponent); } public String getName() { return super.getName(); } public String getDes() { return super.getDes(); } //遍历输出 protected void print() { System.out.println("---------------"+getName()+"----------------"); for(OrganizationComponent organizationcomponent:organizationcomponents) { organizationcomponent.print(); } } } //最后节点类不用储存分支 public class Departments extends OrganizationComponent{ public Departments(String name, String des) { super(name, des); } public String getName() { return super.getName(); } public String getDes() { return super.getDes(); } @Override protected void print() { System.out.println(getName()); } } 直接调用(自己对各个类进行组合,形成自定义的等级关系) //3. 直接调用 public class Client { public static void main(String[] args) { OrganizationComponent university = new University("惠州学院","惠州大学"); //创建院级 OrganizationComponent computerCollege = new College("计算机学院","我的学院"); OrganizationComponent infoCollege = new College("信息学院","我以前的学院"); //创建专业 computerCollege.add(new Departments("软件工程", "我的专业")); computerCollege.add(new Departments("计算机技术", "我的第一专业")); infoCollege.add(new Departments("信息工程", "我不是很了解的专业")); infoCollege.add(new Departments("电子信息工程", "我不了解的专业")); //将部门加入学校 university.add(computerCollege); university.add(infoCollege); //输出 university.print(); } } 组合模式的注意事项和细节 简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题。具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动.方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的 树形结构需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式.要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式 5 外观模式 概述:

一种可以隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口的设计模式。

强调的是对功能调用的进一步抽象。

特点:

向现有的系统添加一个接口,来隐藏系统的复杂性。

客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。

在客户端和复杂系统之间再加一层,这一层将调用顺序、依赖关系等处理好。

通过定义一个一致的接口,用以屏蔽内部子系统的细节,是的调用端只与这个接口发生调用,无需关注调用的细节。

角色: 外观类(Facade): 为调用端提供统一的调用接口, 外观类知道哪些子系统负责处理请求,从而将调用端的请求代 理给适当子系统对象调用者(Client): 外观接口的调用者子系统的集合:指模块或者子系统,处理 Facade 对象指派的任务,他是功能的实际提供者 步骤代码实现: 创建具体实现功能的类 //1、创建某类 public class Rectangle { public void draw() { System.out.println("Rectangle::draw()"); } } public class Square{ public void draw() { System.out.println("Square::draw()"); } } public class Circle { public void draw() { System.out.println("Circle::draw()"); } } 创建外观类用于抽线功能 //2、创建外观类 public class ShapeMaker { private Shape circle; private Shape rectangle; private Shape square; public ShapeMaker() { //内部聚合类 circle = new Circle(); rectangle = new Rectangle(); square = new Square(); } public void drawCircle(){ circle.draw(); } public void drawRectangle(){ rectangle.draw(); } public void drawSquare(){ square.draw(); } } 客户端调用 //3、客户端调用 public class FacadePatternDemo { public static void main(String[] args) { ShapeMaker shapeMaker = new ShapeMaker(); shapeMaker.drawCircle(); shapeMaker.drawRectangle(); shapeMaker.drawSquare(); } } 6 享元模式 概述:

一种主要用于减少创建对象的数量,以减少内存占用和提高性能的设计模式。

核心思想是像java的String那样子,创建字符串是先放入缓冲池,当再次创建相同字符串时会直接使用缓冲池中已有的例子,否则才创建新的String对象。

特点:

运用共享技术有效的支持大量细粒度的对象。

常用于系统底层开发,解决系统底层问题。

可用于解决重复对象内存浪费的问题。

经常用于池技术。

角色:

1、FlyWeight(抽象类):定义出外部状态以及内部状态

2、FlyWeight实现类

FlyWeight实现类1:内部状态类:对象得以依赖分别的标志,是随环境改变的,不可共享的。FlyWeight实现类2:内部状态类:储存在对象内部的且不会随对象改变的,可以共享的类。

3、FlyWeightFactory(工厂类):可以取出想要的FlyWeight类。缓冲层。构建池的容器。提供从池中获取对象的相关方法

类图实例:

享元模式类图示例

步骤代码实现: 创建一个实例对象接口 public interface Shape { void draw(); } 创建实现接口的实体类 public class Circle implements Shape { private String color; private int x; private int y; private int radius; public Circle(String color){ this.color = color; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public void setRadius(int radius) { this.radius = radius; } @Override public void draw() { System.out.println("Circle: Draw() [Color : " + color +", x : " + x +", y :" + y +", radius :" + radius); } } 创建一个工厂,生成基于给定信息的实体类的对象 public class ShapeFactory { private static final HashMap circleMap = new HashMap(); public static Shape getCircle(String color) { Circle circle = (Circle)circleMap.get(color); if(circle == null) { circle = new Circle(color); circleMap.put(color, circle); System.out.println("Creating circle of color : " + color); } return circle; } }

这里就使用了一个HashMap来进行处理数据,当在HashMap中找不到数据时才会创建新的对象。

使用该工厂,通过传递颜色信息来获取实体类的对象 public class FlyweightPatternDemo { private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" }; public static void main(String[] args) { for(int i=0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3