策略模式和适配器模式

Author Avatar
Euan 11月 08, 2019
  • 在其它设备中阅读本文章

策略模式和适配器模式

一.策略模式

1.实验内容和源程序

Application.java

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
public class Application{
public static void main(String args[]){
GymnasticsGame game=new GymnasticsGame(); //上下文对象
game.setStrategy(new StrategyOne()); //上下文对象使用策略一
Person zhang=new Person();
zhang.setName("张三");
double [] a={9.12,9.25,8.87,9.99,6.99,7.88};
Person li=new Person();
li.setName("李四");
double [] b={9.15,9.26,8.97,9.89,6.97,7.89};
zhang.setScore(game.getPersonScore(a));
li.setScore(game.getPersonScore(b));
System.out.println("使用算术平均值方案:");
System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
game.setStrategy(new StrategyTwo()); //上下文对象使用策略二
zhang.setScore(game.getPersonScore(a));
li.setScore(game.getPersonScore(b));
System.out.println("使用几何平均值方案:");
System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
game.setStrategy(new StrategyThree()); //上下文对象使用策略三
zhang.setScore(game.getPersonScore(a));
li.setScore(game.getPersonScore(b));
System.out.println("使用(去掉最高、最底)算术平均值方案:");
System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());
System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());
}
}
class Person{
String name;
double score;
public void setScore(double t){
score=t;
}
public void setName(String s){
name=s;
}
public double getScore(){
return score;
}
public String getName(){
return name;
}
}

ComputableStrategy.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface ComputableStrategy{
public abstract double computeScore(double [] a);
}
GymnasticsGame.java
public class GymnasticsGame{
ComputableStrategy strategy;
public void setStrategy(ComputableStrategy strategy){
this.strategy=strategy;
}
public double getPersonScore(double [] a){
if(strategy!=null)
return strategy.computeScore(a);
else
return 0;
}
}

StrategyOne.java

1
2
3
4
5
6
7
8
9
10
public class StrategyOne implements ComputableStrategy{
public double computeScore(double [] a){
double score=0,sum=0;
for(int i=0;i<a.length;i++){
sum=sum+a[i];
}
score=sum/a.length;
return score;
}
}

StrategyThree.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Arrays;
public class StrategyThree implements ComputableStrategy{
public double computeScore(double [] a){
if(a.length<=2)
return 0;
double score=0,sum=0;
Arrays.sort(a);
for(int i=1;i<a.length-1;i++){
sum=sum+a[i];
}
score=sum/(a.length-2);
return score;
}
}

StrategyTwo.java

1
2
3
4
5
6
7
8
9
10
11
public class StrategyTwo implements ComputableStrategy{
public double computeScore(double [] a){
double score=0,multi=1;
int n=a.length;
for(int i=0;i<a.length;i++){
multi=multi*a[i];
}
score=Math.pow(multi,1.0/n);
return score;
}
}

2.实验执行结果

Kq2lo8.png

3.本次收获体会

创建一个能够根据所传递对象的不同而具有不同行为的方法被称为策略设计模式;这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分。策略就是传递进去的参数对象,它包含要执行的代码。

二.适配器模式

1.实验内容和源程序

Application.java

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
public class Application{
public static void main(String args[]){
ThreeElectricOutlet outlet; //目标接口(三相插座)
Wash wash=new Wash(); //洗衣机
outlet=wash; //洗衣机插在三相插座上
System.out.println("使用三相插座接通电流:");
outlet.connectElectricCurrent(); //接通电流,开始洗衣服
TV tv=new TV(); //电视机
TreeElectricAdapter adapter=new TreeElectricAdapter(tv);//把电视插在适配器上
outlet=adapter; //适配器插在三相插座上
System.out.println("使用三相插座接通电流:");
outlet.connectElectricCurrent(); //接通电流,开始播放电视节目
}
}
class Wash implements ThreeElectricOutlet{ //洗衣机使用三相插座
String name;
Wash(){
name="黄河洗衣机";
}
Wash(String s){
name=s;
}
public void connectElectricCurrent(){
turnOn();
}
public void turnOn(){
System.out.println(name+"开始洗衣物。");
}
}
class TV implements TwoElectricOutlet{ //电视机使用两相插座
String name;
TV(){
name="长江电视机";
}
TV(String s){
name=s;
}
public void connectElectricCurrent(){
turnOn();
}
public void turnOn(){
System.out.println(name+"开始播放节目。");
}
}

ThreeElectricOutlet.java

1
2
3
public interface ThreeElectricOutlet{
public abstract void connectElectricCurrent();
}

TreeElectricAdapter.java

1
2
3
4
5
6
7
8
9
public class TreeElectricAdapter implements ThreeElectricOutlet{
TwoElectricOutlet outlet;
TreeElectricAdapter(TwoElectricOutlet outlet){
this.outlet=outlet;
}
public void connectElectricCurrent(){
outlet.connectElectricCurrent();
}
}

TwoElectricOutlet.java

1
2
3
public interface TwoElectricOutlet{
public abstract void connectElectricCurrent();
}

2.实验执行结果

Kq2Qdf.png

3.本次收获体会

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

三.双向适配器模式

1.实验内容和源程序

Application.java

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
public class Application{
public static void main(String args[]){
ElectricOutlet outlet; //目标接口(三相+双相插座)
Wash wash=new Wash(); //洗衣机
outlet=wash; //洗衣机插在插座上
System.out.println("使用多功能插座接通电流:");
outlet.connectElectricCurrent(); //接通电流,开始洗衣服
TV tv=new TV(); //电视机
outlet=tv; //电视自己插在插座上
System.out.println("使用多功能插座接通电流:");
outlet.connectElectricCurrent(); //接通电流,开始播放电视节目
}
}
class Wash implements ElectricOutlet{ //洗衣机使用三相插座
String name;
Wash(){
name="黄河洗衣机";
}
Wash(String s){
name=s;
}
public void connectElectricCurrent(){
turnOn();
}
public void turnOn(){
System.out.println(name+"开始洗衣物。");
}
}
class TV implements ElectricOutlet{ //电视机使用两相插座
String name;
TV(){
name="长江电视机";
}
TV(String s){
name=s;
}
public void connectElectricCurrent(){
turnOn();
}
public void turnOn(){
System.out.println(name+"开始播放节目。");
}
}

ElectricAdapter.java

1
2
3
4
5
6
7
8
9
10
public class ElectricAdapter implements ThreeElectricOutlet
{
ElectricOutlet outlet;
ElectricAdapter(ElectricOutlet outlet){
this.outlet=outlet;
}
public void connectElectricCurrent(){
outlet.connectElectricCurrent();
}
}

ElectricOutlet.java

1
2
3
public interface ElectricOutlet{
public abstract void connectElectricCurrent();
}

ThreeElectricOutlet.java

1
2
3
public interface ThreeElectricOutlet{
public abstract void connectElectricCurrent();
}

2.实验执行结果

Kq2MeP.png

3.本次收获体会

掌握了双向适配器

本文使用 CC BY-NC-SA 3.0 中国大陆 协议许可
具体请参见 知识共享协议

本文链接:https://zyhang8.github.io/2019/11/08/design-exp3/