上篇文章我们学习了几种创建型模式 的设计模式,那么本篇文章就继续来学习一下结构型模式的几个常用设计模式。
一、代理模式(Proxy Pattern)
代理模式即为其它对象提供一种代理控制对这个对象的访问。在代理模式中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。代理模式的机构图如下:
Subject类中定义一个抽象request()方法,RealSubject和Proxy共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。
1.Subject类代码如下:
1 2 3
| public abstract class Subject { public abstract void request(); }
|
2.RealSubject集成Subject类
1 2 3 4 5 6 7
| public class RealSubject extends Subject{
@Override public void request() { System.out.println("Real Request"); } }
|
3.Proxy实现Subject类
1 2 3 4 5 6 7 8 9 10 11
| public class Proxy extends Subject { private RealSubject mRealSubject;
@Override public void request() { if(mRealSubject==null) { mRealSubject=new RealSubject(); } mRealSubject.request(); } }
|
4.代理测试类
1 2 3 4 5 6 7
| public class ProxyTest {
public static void main(String[] args) { Proxy proxy=new Proxy(); proxy.request(); } }
|
输出结果:
Real Request
二、装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。RedShapeDecorator 是实现了 ShapeDecorator 的实体类。DecoratorPatternDemo,我们的演示类使用 RedShapeDecorator 来装饰 Shape 对象。UML图如下:
1.创建Shape接口
1 2 3
| public interface Shape { void draw(); }
|
2.创建Circle类和Rectangle类并实现Shape接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Circle implements Shape {
@Override public void draw() { System.out.println("Draw Circle"); }
}
public class Rectangle implements Shape {
@Override public void draw() { System.out.println("Draw Rectangle"); }
}
|
3.创建实现了 Shape 接口的抽象装饰类
1 2 3 4 5 6 7 8 9 10 11
| public abstract class ShapeDecorator implements Shape { protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) { this.decoratedShape=decoratedShape; }
public void draw() { decoratedShape.draw(); } }
|
4.创建RedShapeDecorator装饰类并继承ShapeDecorator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) { super(decoratedShape); }
@Override public void draw() { decoratedShape.draw(); setRedBorder(decoratedShape); }
private void setRedBorder(Shape decoratedShape) { System.out.println("Red Border Corlor"); }
}
|
5.装饰模式测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class DecoratorTest { public static void main(String[] args) { Shape circle=new Circle(); Shape redCircle=new RedShapeDecorator(new Circle());
Shape redRectangle=new RedShapeDecorator(new Rectangle()); System.out.println("Circle with normal border"); circle.draw();
System.out.println("Circle whit red border"); redCircle.draw();
System.out.println("Rectangle with red border"); redRectangle.draw();
} }
|
输出结果:
Circle with normal border
Draw Circle
Circle whit red border
Draw Circle
Red Border Corlor
Rectangle with red border
Draw Rectangle
Red Border Corlor
三、适配器模式
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。通常来说,在软件开发中,系统的数据和行为都正确,但接口不符合时,我们应该考虑用适配器,目的是使控制范围之外的一个原有对象与某个接口匹配。
现在假定在我们的应用中使用了两种地图,分别是Google地图和Baidu地图。这两个地图接口对我们而言是隐藏不可修改的,但是由于我们应用的特殊需求,可能会使用两个地图获取位置。那么此时我们就可以用适配器模式来实现。
1.当前我们拥有百度地图和Google地图两个接口均可以获取地理位置。
1 2 3 4 5 6 7 8 9 10 11 12
| public class BaiduMap { public String getBaiduLocation() { return "this is baidu location"; } }
public class GoogleMap { public String getGoogleLocation() { return "this is Google location"; } }
|
2.创建一个Map接口
1 2 3
| public interface Map { String getLocation(String mapType); }
|
3.创建LocationAdapter实现Map接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class LocationAdapter implements Map { @Override public String getLocation(String mapType) { String location=""; switch(mapType) { case "Baidu": location=new BaiduMap().getBaiduLocation(); break; case "Google": location=new GoogleMap().getGoogleLocation(); break; } return location; } }
|
3.测试适配器模式
1 2 3 4 5 6 7 8 9
| public class AdapterTest {
public static void main(String[] args) { LocationAdapter adapter=new LocationAdapter(); System.out.println(adapter.getLocation("Baidu")); System.out.println(adapter.getLocation("Google")); }
}
|
输出结果:
this is baidu location
this is Google location