GOF Structure 2

Flyweight 享元模式
官方解释:

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

Flyweight 对象可用于不同的context中,本身固有的状态( ( 内部状态) ) 不随context发生变化,而其他的状态( ( 外部状态) ) 随context 而 变化。

一个享元对象的内部状态在对象被创建出来以后就不再改变。

享元模式如何与工厂模式配合?Flyweight fw = new ConcreteFlyweight();

UML:(享元接口,具体享元,享元工厂)

1

个人理解:

享元就是将对象们共享的部分抽出来,然后单独作为一个类/对象,作为之前对象的一个传入参数使用。

//当享元对象不是太大时,完全没有必要这么设计……

应用:

汽车厂商想要制造多种类型的车,每类车的长宽高是确定的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public interface Flyweight{ //Flyweight.java
public double getHeight();
public double getWidth();
public double getLength();
public void printMess(String mess);
}

import java.util.HashMap; //FlyweightFactory.java
public class FlyweightFactory{
private HashMap<String,Flyweight> hashMap;
static FlyweightFactory factory=new FlyweightFactory();
private FlyweightFactory(){
hashMap=new HashMap<String,Flyweight>();
}
public static FlyweightFactory getFactory(){
return factory;
}
public synchronized Flyweight getFlyweight(String key){
if(hashMap.containsKey(key))
return hashMap.get(key);
else{
double width=0,height=0,length=0;
String [] str=key.split("#");
width=Double.parseDouble(str[0]);
height=Double.parseDouble(str[1]);
length=Double.parseDouble(str[2]);
Flyweight ft=new ConcreteFlyweight(width,height,length);
hashMap.put(key,ft);
return ft;
}
}
class ConcreteFlyweight implements Flyweight{
private double width;
private double height;
private double length;
private ConcreteFlyweight(double width,double height,double length){
this.width=width;
this.height=height;
this.length=length;
}
public double getHeight(){
return height;
}
public double getWidth(){
return width;
}
public double getLength(){
return length;
}
public void printMess(String mess){
System.out.print(mess);
System.out.print(" 宽度:"+width);
System.out.print(" 高度:"+height);
System.out.println("长度:"+length);
}
}
}
public class Car{ //Car.java 一个具成员变量为享元类的类
Flyweight flyweight;
String name,color;
int power;
Car(Flyweight flyweight,String name,String color,int power){
this.flyweight=flyweight;
this.name=name;
this.color=color;
this.power=power;
}
public void print(){
System.out.print(" 名称:"+name);
System.out.print(" 颜色:"+color);
System.out.print(" 功率:"+power);
System.out.print(" 宽度:"+flyweight.getWidth());
System.out.print(" 高度:"+flyweight.getHeight());
System.out.println("长度:"+flyweight.getLength());
}
}
public class Application{ //Application.java 用户创建一个具体类时用到享元类
public static void main(String args[]) {
FlyweightFactory factory=FlyweightFactory.getFactory();
double width=1.82,height=1.47,length=5.12;
String key=""+width+"#"+height+"#"+length;
Flyweight flyweight=factory.getFlyweight(key);
Car audiA6One=new Car(flyweight,"奥迪A6","黑色",128);
Car audiA6Two=new Car(flyweight,"奥迪A6","灰色",160);
audiA6One.print();
audiA6Two.print();
width=1.77;
height=1.45;
length=4.63;
key=""+width+"#"+height+"#"+length;
flyweight=factory.getFlyweight(key);
Car audiA4One=new Car(flyweight,"奥迪A4","蓝色",126);
Car audiA4Two=new Car(flyweight,"奥迪A4","红色",138);
flyweight.printMess(" 名称:奥迪A4 颜色:蓝色 功率:126");
flyweight.printMess(" 名称:奥迪A4 颜色:红色 功率:138");
}
}
Facade 门面模式
官方解释:

为系统中的一组接口提供一个一致的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

外观模式是简化用户和子系统进行交互的成熟模式,外观模式的关键是为子系统提供一个称作外观的类,该外观类的实例负责和子系统中类的实例打交道。当用户想要和子系统中的若干个类的实例打交道时,可以代替地和子系统的外观类的实例打交道。

UML:(子系统,外观)

2

个人理解:

为用户提供一个简化操作视图,自动化操作流程,类似傻瓜相机一键拍照。

应用:

报社的广告系统有三个类CheckWord、Charge和TypeSetting类,各个类的职责如下:CheckWord类负责检查广告内容含有的字符数量;Charge类的实例负责计算费用;TypeSetting的实例负责对广告进行排版。使用外观模式简化用户和上述子系统所进行的交互。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public class CheckWord{ //CheckWord.java
public final int basicAmount=85;
String advertisement;
int amount;
public CheckWord(String advertisement){
this.advertisement=advertisement;
}
public void setChargeAmount(){
amount=advertisement.length()+basicAmount; //计算出计费字符数目
}
public int getAmount(){
return amount;
}
}
public class Charge{ //Charge.java
public final int basicCharge=12;
CheckWord checkWord;
Charge(CheckWord checkWord){
this.checkWord=checkWord;
}
public void giveCharge(){
int charge=checkWord.getAmount()*basicCharge;
System.out.println("广告费用:"+charge+"元");
}
}

public class TypeSeting{ //TypeSeting.java
String advertisement;
public TypeSeting(String advertisement){
this.advertisement=advertisement;
}
public void typeSeting(){
System.out.println("广告排版格式:");
System.out.println("********");
System.out.println(advertisement);
System.out.println("********");
}
}
public class ClientServerFacade{ //ClientServerFacade.java
private CheckWord checkWord;
private Charge charge;
private TypeSeting typeSeting;
String advertisement;
public ClientServerFacade(String advertisement){
this.advertisement=advertisement;
checkWord=new CheckWord(advertisement);
charge=new Charge(checkWord);
typeSeting=new TypeSeting(advertisement);
}
public void doAdvertisement(){
checkWord.setChargeAmount();
charge.giveCharge();
typeSeting.typeSeting();
}
}
public class Application{ //Application.java 用户交互
public static void main(String args[]){
ClientServerFacade clientFacade;
String clientAdvertisement="鹿花牌洗衣机,价格2356元,联系电话:1234567";
clientFacade=new ClientServerFacade(clientAdvertisement);
clientFacade.doAdvertisement();
}
}
Proxy 代理模式
官方解释:

代理模式是为对象提供一个代理,代理可以控制对它所代理的对象的访问。

UML:(抽象主体,真实主体,代理)

3

个人理解:

代理类使用另功能类完成用户所需的功能,同时加上一些管控策略。

应用:

用户输入三个代表三角形三边长度的数值,代理对象验证用户输入的三个数值是否能构成三角形,如果能构成三角形,就创建一个三角形对象,并让三角形对象计算自身的面积。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public  interface Geometry{ //Geometry.java 
public double getArea();
}
public class Triangle implements Geometry{ //Triangle.java
double sideA,sideB,sideC,area;
public Triangle(double a,double b,double c) {
sideA=a;
sideB=b;
sideC=c;
}
public double getArea(){
double p=(sideA+sideB+sideC)/2.0;
area=Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC)) ;
return area;
}
}
public class TriangleProxy implements Geometry{ //TriangleProxy.java
double sideA,sideB,sideC;
Triangle triangle;
public void setABC(double a,double b,double c) {
sideA=a;
sideB=b;
sideC=c;
}
public double getArea(){
if(sideA+sideB>sideC&&sideA+sideC>sideB&&sideB+sideC>sideA){
triangle=new Triangle(sideA,sideB,sideC);
double area=triangle.getArea();
return area;
}
else
return -1;
}
}
import java.util.Scanner; // Application.java
public class Application{
public static void main(String args[]) {
Scanner reader=new Scanner(System.in);
System.out.println("请输入三个数,每输入一个数回车确认");
double a=-1,b=-1,c=-1;
a=reader.nextDouble();
b=reader.nextDouble();
c=reader.nextDouble();
TriangleProxy proxy=new TriangleProxy();
proxy.setABC(a,b,c);
double area=proxy.getArea();
System.out.println("面积是:"+area);
}
}