设计模式作业1

1.一个开宝箱游戏的基本描述为:游戏中有多种类型的人物(Role),如战士(Solider)、魔法师(Mage)等,主角的类型只能选择其中一种,且游戏中不再更改。游戏中还有各种宝箱(Box),如装有不同数目金钱的宝箱、装有毒物的宝箱等。当任一种类型的主角打开装有金钱的宝箱时,宝箱中的金钱会增加给主角,同时宝箱的金钱数目变成0;当战士打开装有毒物的宝箱时,战士的生命值(HP)会减少10%,但金钱(Money)增加20%;当魔法师打开装有毒物的宝箱时,魔法师的生命值(HP)会减少30%,但金钱(Money)增加40% 。

请根据上述描述,给出相应类的设计并完整实现,要求你的设计应具有良好的扩展性,如增加新角色类型及箱子种类时,不需要修改已有的设计及实现。

 

类设计:

通过派生不同的子类实现不同角色开启不同箱子产生的不同的效果

//box
public abstract class Box {
	abstract void be_opened(Role role); 
}

//role
public abstract class Role {
	private int money,hp;
	abstract void open_box(Box box);
	abstract void poising();
	
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	public int getHp() {
		return hp;
	}
	public void setHp(int hp) {
		this.hp = hp;
	}
}

//boxes
public class Money_box extends Box{
	private int money;
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	@Override
	void be_opened(Role role) {
		// TODO Auto-generated method stub
		role.setMoney(role.getMoney()+money);
	}
}
public class Poison_box extends Box{
	@Override
	void be_opened(Role role) {
		// TODO Auto-generated method stub
		role.poising();
	}
}

//roles
public class Mage extends Role{
	@Override
	void open_box(Box box) {
		// TODO Auto-generated method stub
		box.be_opened(this);
	}
	@Override
	void poising() {
		// TODO Auto-generated method stub
		this.setHp((int) (getHp()*0.7));
		this.setMoney((int) (getMoney()*1.4));
	}
}

public class Solider extends Role{
	@Override
	void open_box(Box box) {
		// TODO Auto-generated method stub
		box.be_opened(this);
	}

	@Override
	void poising() {
		// TODO Auto-generated method stub
		this.setHp((int) (getHp()*0.9));
		this.setMoney((int) (getMoney()*1.2));
	}
}

2.题目

给出适当的类设计和相应的代码:  有一个只能放进不能取出的盒子, 最多可放8个水果, 不一定一天放入。水果只是苹果和桔子两种, 它们放入盒子前的原始重量分别为50和30, 放入盒子后, 由于丢失水分, 它们的重量减轻, 苹果和桔子每天分别减轻4和3, 直到达到各自原始重量的3/5后, 不再减轻重量。盒子的功能有:  输出盒子中苹果的数量; 输出盒子中桔子的数量; 输出一天来盒子中水果减轻的总重量; 输出当前水果的总重量。

 

代码分析:这里水果放入为随机生成,假设考虑每两小时可选择是否放入水果及水果种类,按每六小时苹果重量减一,橘子重量每八小时减一

Fruits:

package test1.prec;

public abstract class Fruits {
	protected String name;
	private int weight,min_weight,time;
	Fruits(){
		setTime(0);
		name=new String("NULL");
		weight=0;
		min_weight=0;
	}
	abstract void reduce();
	void set_name(String name) {
		this.name=new String(name);
	}
	void set_weight(int weight) {
		this.weight=weight;
	}
	String get_name() {
		return name;
	}
	int get_weight() {
		return weight;
	}
	void set_min(int min) {
		this.min_weight=min;
	}
	int get_min() {
		return min_weight;
	}
	public int getTime() {
		return time;
	}
	public void setTime(int time) {
		this.time = time;
	}
}

Apples:

package test1.prec;

public class Apples extends Fruits {
	Apples(){
		this.set_name("Apple");
		this.setTime(0);
		this.set_weight(50);
		this.set_min(30);
	}
	@Override
	void reduce() {
		// TODO Auto-generated method stub
		this.set_weight(this.get_weight()-1);
	}

}

Oranges:

package test1.prec;

public class Oranges extends Fruits{
	Oranges(){
		this.set_name("Orange");
		this.setTime(0);
		this.set_weight(30);
		this.set_min(18);
	}
	@Override
	void reduce() {
		// TODO Auto-generated method stub
		this.set_weight(get_weight()-1);
	}
	
}

Box:由exist()函数记录盒子存在期间所有统计操作

package test1.prec;

public class Box {
	protected Fruits[] fruits;
	protected int size,len,time;
	protected int d_r,s_w;
	protected int a_num,o_num;
	Box(int time){
		this.size=8;
		this.len=0;
		this.time=time;		//为了简化按小时计时测试
		this.fruits=new Fruits[size];
	}
	void put_fruit(int k,Fruits fruit) {
		if(((len+k-1)<size)&&(k-1>=0)&&(k>0)) {
				for(int i=0;i<=k-1;i++) {
						if(fruit.name.equals("Apple")) {
							fruits[len]=new Apples();
							this.a_num=this.a_num+1;//放入了1苹果
						}
						else {
							this.o_num=this.o_num+1;
							fruits[len]=new Oranges();//放入了1桔子
						}
						len++;
				}
		}
	}
	void sum_w() {
		for(int i=0;i<8&&fruits[i]!=null;i++) {
			s_w=s_w+fruits[i].get_weight();
		}
		System.out.println("当前水果共重:"+s_w);
	}
	void exist() {
		int an = 0,on = 0;
		int j=0;
		for(;j<=time;j+=2) {
			an=(int)(Math.random()*(9-len));
			on=(int)(Math.random()*(9-len));
			if(len<8) {
				this.put_fruit(an, new Apples());
				this.put_fruit(on, new Oranges());
				
			}
			for(int i=0;(i<8)&&(fruits[i]!=null);i++) {
				if(fruits[i].get_min()<fruits[i].get_weight()) {
					if((fruits[i].getTime()!=0)&&((fruits[i].getTime()%6==0&&fruits[i].get_name().equals("Apple"))||(fruits[i].getTime()%8==0)&&fruits[i].get_name().equals("Orange"))) {
						fruits[i].reduce();
						d_r=d_r+1;
					}
				}
				fruits[i].setTime(fruits[i].getTime()+2);
			}
			if(j%24==0&&j!=0) {
				System.out.println("第"+(j/24)+"天水分共减少:"+d_r);
				d_r = 0;
			}
		}
		System.out.println("第"+(j/24+1)+"天水分共减少:"+d_r);
		System.out.println("共有"+a_num+"个苹果和"+o_num+"个桔子");
		sum_w();
		
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Box box=new Box(192);
		box.exist();
		
	}

}

输出样例:

3.题目

class B {

public:

   B(int n):data(n) { }

   int Data( ) const { return data; }

   void g1( );

   void g2( );

   void g3( );

private:  

   const int data;

};

void f( B& b ) {

   int condition = b.Data( );           

   if(condition == 1) { b.g1( ); }

   else if(condition == 5) { b.g2( ); }

   else if(condition == 9) { b.g3( ); }

}

当把此程序交给用户试用时, 针对函数f, 用户提出了一项新的要求: 当condition为100时, 依次执行b的成员函数g1( )和g2( )。经过进一步了解, 小王获悉: 以后可能还要增加处理condition的值是其它数值时的情况, 但这些需要分别处理的不同条件值的个数肯定不多。小王希望他写出的代码既能满足上述要求, 又不用每次都改写f的代码。请你帮小王重新设计, 使得新设计能够满足小王的愿望。简要说明你的设计思想, 给出实现代码。

 

设计思想:创建一个纯虚函数类,由其子类分别实现condition不同值下函数需要应对的不同情况,在不同情况下传入不同的对象指针调用不同的类对象函数。

类设计:

class B {
public:
	B(int n) :data(n) { }
	int Data() const { return data; }
	void g1();
	void g2();
	void g3();
private:
	const int data;
};

class A  //虚基类
{
public:
	virtual void func(B& b) = 0;
};

class A1 :public A
{
public:
	void func(B& b){
		b.g1();
	}
};
class A5 :public A
{
public:
	void func(B& b){
		b.g2();
	}
};
class A9 :public A
{
public:
	void func(B& b){
		b.g3();
	}
};
class A100 :public A
{
public:
	void func(B& b){
		b.g1();
b.g2();
	}
};

void f(B& b,A* a) {
	a->func(b);
}
//传入A1则对应condition=1的情况,以此类推

ps:作业笔记

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值