7.デザインモードデコレータモードで、伝説の世界に戻ります

今日、私はデザインパターンの旅を続け、デコレータパターン、国際的な慣習を紹介します。最初に定義を見てみましょう。

デコレーターモード:機能を拡張するために、デコレーターは統合よりも柔軟な代替手段を提供し、オブジェクトに責任を動的に付加します。

まず、デコレータモードが機能する場所について簡単に説明します。クラスを設計するときは、このクラスにいくつかの補助関数を追加する必要があり、このクラスのコードを変更する必要はありません。現時点では、デコレータモードが威力を発揮しています。時間です。ここにも反映されている原則があります。クラスは拡張のために開かれ、変更のために閉じられるべきです。

さて、話題に移りましょう。今日はそこで映画を見ていて、私が若い頃にゲームフィールドの血の風を突然思い出しました。はは、ゲームの背景でデコレータモードを紹介しましょう。ゲームをプレイした兄弟は、ゲームの各キャラクターが武器、靴、リストバンド、リング、さまざまなルビー、サファイア、トパーズなどを持っていることを知っておく必要があります。

次の要件から始めます。ゲームの機器システム、基本要件を設計し、さまざまな宝石をはめ込んだ後、攻撃力と各機器の説明を計算します。

特定の要件:

1.武器(攻撃力20)、リング(攻撃力5)、ブレーサー(攻撃力5)、靴(攻撃力5)

2.サファイア(攻撃力5 /個)、トパーズ(攻撃力10 /個)、ルビー(攻撃力15 /個)

3.各装置は自由に3個をはめ込むことができます

さて、要件が導入されましたが、もちろん、私のデザインについて文句を言わないでください。ニマシューズの攻撃力はどこから来たのですか?クリティカルな瞬間に人々を襲う可能性があります。予備的なアイデアから始めましょう。長年のオブジェクト指向の経験に基づいて、次のように設計できます。
ここに画像の説明を挿入

このように設計した場合、私はそれに依存しています。何百ものカテゴリを作成し、ランダムに2つの宝石を追加する必要があります。ハハ、指数関数的な成長について聞いたことがありますか?残業する準備をしてください。

多分あなたはまだこのように設計しています:スーパークラスを書き、それにさまざまな宝石を設定してから、攻撃力の計算で、いくつかの種類の宝石がある場合、おめでとうございます、コードの量はそれほど多くありませんが、武器を追加するだけです、さらにいくつのIFを記述する必要がありますか?

上記の可能な設計の一部はあまり良くありません。デコレータパターンを統合する方法を見てみましょう。

一つ目はスーパークラスの装備です

package com.zhy.pattern.decorator;
 
/**
 * 装备的接口
 * 
 * @author zhy
 * 
 */
public interface IEquip
{
 
	/**
	 * 计算攻击力
	 * 
	 * @return
	 */
	public int caculateAttack();
 
	/**
	 * 装备的描述
	 * 
	 * @return
	 */
	public String description();
}

次に、武器、指輪、手首、靴があります

package com.zhy.pattern.decorator;
 
/**
 * 武器
 * 攻击力20
 * @author zhy
 * 
 */
public class ArmEquip implements IEquip
{
 
	@Override
	public int caculateAttack()
	{
		return 20;
	}
 
	@Override
	public String description()
	{
		return "屠龙刀";
	}
 
}
package com.zhy.pattern.decorator;
 
/**
 * 戒指
 * 攻击力 5
 * @author zhy
 *
 */
public class RingEquip implements IEquip
{
 
	@Override
	public int caculateAttack()
	{
		return 5;
	}
 
	@Override
	public String description()
	{
		return "圣战戒指";
	}
 
}
package com.zhy.pattern.decorator;
 
/**
 * 护腕
 * 攻击力 5
 * @author zhy
 *
 */
public class WristEquip implements IEquip
{
 
	@Override
	public int caculateAttack()
	{
		return 5;
	}
 
	@Override
	public String description()
	{
		return "圣战护腕";
	}
 
}
package com.zhy.pattern.decorator;
 
/**
 * 鞋子
 * 攻击力 5
 * @author zhy
 * 
 */
public class ShoeEquip implements IEquip
{
 
	@Override
	public int caculateAttack()
	{
		return 5;
	}
 
	@Override
	public String description()
	{
		return "圣战靴子";
	}
 
}

次に、もちろん、装飾、宝石、最初のスーパークラス

package com.zhy.pattern.decorator;
 
/**
 * 装饰品的接口
 * @author zhy
 *
 */
public interface IEquipDecorator extends IEquip
{
	
}

サファイア、トパーズ、ルビーダウン

package com.zhy.pattern.decorator;
 
/**
 * 蓝宝石装饰品
 * 每颗攻击力+5
 * @author zhy
 * 
 */
public class BlueGemDecorator implements IEquipDecorator
{
	/**
	 * 每个装饰品维护一个装备
	 */
	private IEquip equip;
 
	public BlueGemDecorator(IEquip equip)
	{
		this.equip = equip;
	}
 
	@Override
	public int caculateAttack()
	{
		return 5 + equip.caculateAttack();
	}
 
	@Override
	public String description()
	{
		return equip.description() + "+ 蓝宝石";
	}
 
}
package com.zhy.pattern.decorator;
 
/**
 * 黄宝石装饰品
 * 每颗攻击力+10
 * @author zhy
 * 
 */
public class YellowGemDecorator implements IEquipDecorator
{
	/**
	 * 每个装饰品维护一个装备
	 */
	private IEquip equip;
 
	public YellowGemDecorator(IEquip equip)
	{
		this.equip = equip;
	}
 
	@Override
	public int caculateAttack()
	{
		return 10 + equip.caculateAttack();
	}
 
	@Override
	public String description()
	{
		return equip.description() + "+ 黄宝石";
	}
 
}
package com.zhy.pattern.decorator;
 
/**
 * 红宝石装饰品 每颗攻击力+15
 * 
 * @author zhy
 * 
 */
public class RedGemDecorator implements IEquipDecorator
{
	/**
	 * 每个装饰品维护一个装备
	 */
	private IEquip equip;
 
	public RedGemDecorator(IEquip equip)
	{
		this.equip = equip;
	}
 
	@Override
	public int caculateAttack()
	{
		return 15 + equip.caculateAttack();
	}
 
	@Override
	public String description()
	{
		return equip.description() + "+ 红宝石";
	}
 
}

さて、これで終わりです。必要な関数を実装しました。クラスごとに明確でシンプルです。以下のテストを見てみましょう。

package com.zhy.pattern.decorator;
 
public class Test
{
	public static void main(String[] args)
	{
		// 一个镶嵌2颗红宝石,1颗蓝宝石的靴子
		System.out.println(" 一个镶嵌2颗红宝石,1颗蓝宝石的靴子");
		IEquip equip = new RedGemDecorator(new RedGemDecorator(new BlueGemDecorator(new ShoeEquip())));
		System.out.println("攻击力  : " + equip.caculateAttack());
		System.out.println("描述 :" + equip.description());
		System.out.println("-------");
		// 一个镶嵌1颗红宝石,1颗蓝宝石的武器
		System.out.println(" 一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器");
		equip = new RedGemDecorator(new BlueGemDecorator(new YellowGemDecorator(new ArmEquip())));
		System.out.println("攻击力  : " + equip.caculateAttack());
		System.out.println("描述 :" + equip.description());
		System.out.println("-------");
	}
}

出力:

 一个镶嵌2颗红宝石,1颗蓝宝石的靴子
攻击力  : 40
描述 :圣战靴子+ 蓝宝石+ 红宝石+ 红宝石

 一个镶嵌1颗红宝石,1颗蓝宝石,1颗黄宝石的武器
攻击力  : 50
描述 :屠龙刀+ 黄宝石+ 蓝宝石+ 红宝石

好むと好まざるとにかかわらず、より多くの機器や宝石が必要な場合は、自由に追加して、楽しく仕事を終えることができます。

おめでとうございます。もう1つのデザインパターン、デコレータパターンを学習しました。

例に基づいた定義を理解したので、これ以上言う必要はありません。

Java APIにはデコレータパターンもあります。Javaを初めて使用する場合は、Javaのさまざまなストリームを覚えておく必要があります。

あなたのデザインはその後より明確になります。

ここに画像の説明を挿入

InputStreamをIEquipとして、FilterInputStreamをIEquipDecoratorとして考えます。これは、設計とほとんど同じです〜

おすすめ

転載: blog.csdn.net/GTC_GZ/article/details/108745449