策略模式(strategy)

一.策略模式是什么

策略模式是一种行为型对象模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换。这样,算法可以独立于使用它的客户端而变化‌‌。

策略者模式的核心思想是将一系列的算法封装到一系列的策略类里,作为一个抽象策略类的子类。具体策略角色包装了相关的算法或行为,而环境角色持有一个策略类的引用,这样可以在不影响到客户端的情况下更换算法‌。

策略者模式的优点在于它使得算法可以在不影响到客户端的情况下发生变化。通过将算法封装到独立的类中,并使它们具有共同的接口,策略者模式允许在运行时选择不同的算法实现,从而提高了程序的灵活性和可扩展性‌

二.类图

三.实例

示例一:

商场打折,一共有两种策略,满300打8折,满400打7折。UML图如下

Buy.java

java 复制代码
package 策略模式;

public class Buy {
	private Discount discount=new Discount();
	private double cost;
	Buy(double cost){
	this.cost=cost;	
	}
	double getcost() {
		return cost;
	}
	Discount getdiscount() {
		return discount;
	}
}

Discount.java

java 复制代码
package 策略模式;

public class Discount {
protected double discountpercent;
protected double discountprice;
void dodiscount(double originalprice) {
	if(originalprice>400.00) {
		new stratage1(originalprice);
	}
	else if(originalprice>300.00) {
		new stratege2(originalprice);
	}
	else {
		new stratege3(originalprice);
	}
	
}
void setdisp(double discountpercent) {
	this.discountpercent=discountpercent;
}
void print(){};
}

Stratege1.java

java 复制代码
package 策略模式;

public class stratage1 extends Discount{
	stratage1(double originalprice){
		print();
		setdisp(0.7);
		discountprice=originalprice*discountpercent;
		System.out.printf("原来的价格是:");
		System.out.println(originalprice);
		System.out.printf("打完折后的价格是:");
		System.out.println(discountprice);
	}

	void print() {
		// TODO Auto-generated method stub
		System.out.println("因为购物的价格在400元以上,打7折");
	}
	
	
}

Stratege2.java

java 复制代码
package 策略模式;

public class stratege2 extends Discount{
	stratege2(double originalprice){
		print();
		setdisp(0.8);
		discountprice=originalprice*discountpercent;
		System.out.printf("原来的价格是:");
		System.out.println(originalprice);
		System.out.printf("打完折后的价格是:");
		System.out.println(discountprice);
	}

	@Override
	void print() {
		// TODO Auto-generated method stub
		System.out.printf("因为商品价格介于300到400之间,打8折");
	}
}

Stratege3.java

java 复制代码
package 策略模式;

public class stratege3 extends Discount{
	stratege3(double originalprice){
		print();
		setdisp(1);
		discountprice=originalprice*discountpercent;
		System.out.printf("原来的价格是:");
		System.out.println(originalprice);
		System.out.printf("打完折后的价格是:");
		System.out.println(discountprice);
	}

	@Override
	void print() {
		// TODO Auto-generated method stub
		System.out.printf("因为商品的价格小于300元,所以不打折\n");

	}
}

A.java(主函数)

java 复制代码
package 策略模式;

public class A {
	public static void main(String[] args) {
		Buy buy1=new Buy(7.0);
		buy1.getdiscount().dodiscount(buy1.getcost());
		Buy buy2=new Buy(360.0);
		buy2.getdiscount().dodiscount(buy2.getcost());
		Buy buy3=new Buy(800.0);
		buy3.getdiscount().dodiscount(buy3.getcost());
}
}

运行结果:

例二.

Hand.java

java 复制代码
package 策略模式2;

public class Hand {
	public static final int HANDVALUE_GUU=0;
	public static final int HANDVALUE_COH=1;
	public static final int HANDVALUE_PAA=2;
	public static final Hand[] hand={
		new Hand(HANDVALUE_GUU),
		new Hand(HANDVALUE_COH),
		new Hand(HANDVALUE_PAA),
	};
	private static final String[] name={
	"石头","剪刀","布",
};
private int handvalue;
public Hand(int handvalue) {
	this.handvalue=handvalue;
}
public static Hand getHand(int handvalue){
	return hand[handvalue];
}
public boolean isStrongerthan(Hand h) {
	return fight(h)==1;
}
public boolean isWeakerthan(Hand h) {
	return fight(h)==-1;
}
private int fight(Hand h) {
	if(this==h) {
		return 0;
	}else if((this.handvalue+1)%3==h.handvalue) {
		return 1;
	}else return -1;
}
public String toString() {
	return name[handvalue];
}
}

Player.java

java 复制代码
package 策略模式2;
public class Player {
	private String name;
	private Strategy strategy;
	private int wincount;
	private int losecount;
	private int gamecount;
	public Player(String name,Strategy strategy) {
		this.name=name;
		this.strategy=strategy;
	}
	public Hand nexthand() {
		return strategy.nexthand();
	}
	public void win() {
		strategy.study(true);
		wincount++;
		gamecount++;
	}
	public void lose() {
		strategy.study(false);
		losecount++;
		gamecount++;
	}	
	public void even() {
		gamecount++;
	}
	public String tostring() {
		return "["+name+":"+gamecount+"games,"+wincount+"win,"+losecount+"lose."+"]";
	}
}

probstrategy.java

java 复制代码
package 策略模式2;
import java.util.Random;
public class Probstrategy implements Strategy {
	private Random random;
	private int prevhandvalue=0;
	private int currenthandvalue=0;
	private int [][]history= {
			{1,1,1},
			{1,1,1},
			{1,1,1},
	};
	public Probstrategy(int seed) {
		random=new Random(seed);
	}
	@Override
	public Hand nexthand() {
		// TODO Auto-generated method stub
		int bet=random.nextInt(getSum(currenthandvalue));
		return new Hand(bet);
	}

	private int getSum(int hv) {
		// TODO Auto-generated method stub
		int sum=0;
		for(int i=0;i<3;i++) {
			sum+=history[hv][i];
		}
		return sum;
	}
	@Override
	public void study(boolean win) {
		// TODO Auto-generated method stub
		if(win) {
			history[prevhandvalue][currenthandvalue]++;
		}
		else {
			history[prevhandvalue][(currenthandvalue+1)%3]++;
			history[prevhandvalue][(currenthandvalue+2)%3]++;

		}
	}

}

winstrategy.java

java 复制代码
package 策略模式2;
import java.util.Random;
public class Winningstrategy implements Strategy {
	private Random random;
private boolean won=false;
private Hand prevhand;
public Winningstrategy(int seed) {
	random=new Random(seed);
}
public Hand nexthand() {
	if(!won) {
		prevhand=Hand.getHand(random.nextInt(3));
	}
	return prevhand;
}
@Override
public void study(boolean win) {
	// TODO Auto-generated method stub
	won=win;
}
}

strategy.java

java 复制代码
package 策略模式2;

public interface Strategy {
public abstract Hand nexthand();
public abstract void study(boolean win);
}

Main.java

java 复制代码
package 策略模式2;

public class Main {
	public static void main(String[] args) {
		if(args.length!=2) {
			System.out.println("Usage java main randomseed1 randomseed2");
			System.out.println("Example :java Main 314 15");
			System.exit(0);
		}
		int seed1=Integer.parseInt(args[0]);
		int seed2=Integer.parseInt(args[1]);
Player player1=new Player("haha",new Winningstrategy(seed1));
Player player2=new Player("xixi",new Probstrategy(seed2));
for(int i=0;i<1000;i++) {
	Hand nexthand1=player1.nexthand();
	Hand nexthand2=player2.nexthand();
if(nexthand1.isStrongerthan(nexthand2)) {
	System.out.println("winner:"+player1);
	player1.win();
	player2.lose();
}else if(nexthand2.isStrongerthan(nexthand1)){
	System.out.println("winner:"+player2);
	player2.win();
	player1.lose();
}
else {
	System.out.println("even");
	player1.even();
	player2.even();
}
}
System.out.println("total resaults:");
System.out.println(player1.tostring());
System.out.println(player2.tostring());
	}
}

运行结果:

习题练习

习题10-1解析:

Random.java

java 复制代码
package 策略模式2;
import java.util.Random;
public class RadomStrategy implements Strategy{
	private Random random;
	public RadomStrategy(int seed) {
		random=new Random(seed);
	}
	@Override
	public Hand nexthand() {
		return Hand.getHand(random.nextInt(3));
	}

	@Override
	public void study(boolean win) {
		// TODO Auto-generated method stub
		
	}

}

Main.java

java 复制代码
package 策略模式2;

public class Main {
	public static void main(String[] args) {
		if(args.length!=3) {
			System.out.println("Usage java main randomseed1 randomseed2");
			System.out.println("Example :java Main 314 15 9");
			System.exit(0);
		}
		int seed1=Integer.parseInt(args[0]);
		int seed2=Integer.parseInt(args[1]);
		int seed3=Integer.parseInt(args[2]);
Player player1=new Player("haha",new Winningstrategy(seed1));
Player player2=new Player("xixi",new Probstrategy(seed2));
Player player3=new Player("hehe",new RadomStrategy(seed3));
for(int i=0;i<1000;i++) {
	Hand nexthand1=player1.nexthand();
	Hand nexthand2=player2.nexthand();
if(nexthand1.isStrongerthan(nexthand2)) {
	System.out.println("winner:"+player1);
	player1.win();
	player3.lose();
}else if(nexthand2.isStrongerthan(nexthand1)){
	System.out.println("winner:"+player2);
	player3.win();
	player1.lose();
}
else {
	System.out.println("even");
	player1.even();
	player3.even();
}
}
System.out.println("total resaults:");
System.out.println(player1.tostring());
System.out.println(player3.tostring());
	}
}

运行结果:

10-2解析:

10-3解析:

10-4解析:

Main.java

java 复制代码
public class Main {
public static void main(String[] args) {
	String[] data= {
			"Dumpty","Baba","Coco","Apple","Elements"
	};
	SortAndPrint sap=new SortAndPrint(data,new SelectionSorter());
	sap.execute();
}
}

SortAndPrint.java

java 复制代码
public class SortAndPrint {
Comparable[]data;
Sorter sorter;
public SortAndPrint(Comparable[] data,Sorter sorter) {
	this.data=data;
	this.sorter=sorter;
}
public void execute() {
	print();
	sorter.sort(data);
	print();
}
public void print() {
	for(int i=0;i<data.length;i++) {
		System.out.print(data[i]+",");
	}
	System.out.println("");
}
}

SelectionSorter.java(简单选择排序)

java 复制代码
public class SelectionSorter implements Sorter {

	@Override
	public void sort(Comparable[] data) {
		// TODO Auto-generated method stub
	for(int i=0;i<data.length-1;i++) {
		int min=i;
		for(int j=i+1;j<data.length;j++) {
			if(data[min].compareTo(data[j])>0) {
				min=j;
			}
		}
		Comparable passingplace=data[min];
		data[min]=data[i];
		data[i]=passingplace;
	}
	}

}

Sorter.java

java 复制代码
import java.lang.Comparable;
public interface Sorter {
public abstract void sort(Comparable[] data);
}

运行结果:

增加一个快速排序

Main.java

java 复制代码
public class Main {
public static void main(String[] args) {
	String[] data= {
			"Dumpty","Baba","Coco","Apple","Elements"
	};
	SortAndPrint sap=new SortAndPrint(data,new SelectionSorter());
	SortAndPrint qsort=new SortAndPrint(data,new QuickSorter());
//	sap.execute();
	System.out.println("快速排序");
	qsort.execute();
}
}

QuickSorter.java

java 复制代码
public class QuickSorter implements Sorter{
Comparable[] data;
	@Override
	public void sort(Comparable[] data) {
		// TODO Auto-generated method stub
		this.data=data;
		qsort(0,data.length-1);
		
	}
	private void qsort(int pre, int post) {
		// TODO Auto-generated method stub
		int saved_pre=pre;
		int saved_post=post;
		Comparable mid=data[(pre+post)/2];
		do {
			while(data[pre].compareTo(mid)<0) {
				pre++;
			}
			while(mid.compareTo(data[post])<0) {
				post--;
			}
			if(pre<=post) {
				Comparable tmp=data[pre];
				data[pre]=data[post];
				data[post]=tmp;
				pre++;
				post--;
			}
		}while(pre<=post);
		if(saved_pre<post) {
			qsort(saved_pre,post);
		}
		if(pre<saved_post) {
			qsort(pre,saved_post);
		}
	}

}

运行结果:

相关推荐
tiger从容淡定是人生1 天前
可审计性:AI时代自动化测试的核心指标
人工智能·自动化·项目管理·策略模式·可用性测试·coo
都说名字长不会被发现2 天前
模版方法 + 策略模式在库存增加/扣减场景下的应用
策略模式·模板方法模式·宏命令·策略聚合·库存设计
默|笙2 天前
【Linux】进程概念与控制(2)_进程控制
java·linux·策略模式
枫叶林FYL4 天前
Agent/Teakenote 系统(Swarm 架构)深度技术报告
架构·策略模式
苏渡苇5 天前
枚举的高级用法——用枚举实现策略模式和状态机
java·单例模式·策略模式·枚举·状态机·enum
harder3217 天前
Swift 面向协议编程的 RMP 模式
开发语言·ios·mvc·swift·策略模式
skywalk81637 天前
esxi8 虚拟机中怎么安装mac os(纯AI回答,未实践)
策略模式·esxi
廖圣平8 天前
从零开始,福袋直播间脚本研究【八】《策略模式》
开发语言·python·bash·策略模式
爱学习 爱分享11 天前
简单工厂模式和策略模式的区别
简单工厂模式·策略模式
xcntime14 天前
Python中print函数如何实现不换行输出?
策略模式