浅析Java设计模式(二)

上篇文章我们学习了几种创建型模式 的设计模式,那么本篇文章就继续来学习一下结构型模式的几个常用设计模式。

一、代理模式(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


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!