常用设计模式:装饰器模式和策略模式

装饰器模式和策略模式

装饰器模式

定义:在不改变原有对象的基础上,将功能附加到对象上
比如原有一个拍照的功能,在这个功能的基础上,添加美颜和滤镜

//定义原有功能接口
public interface Component {
	void operation();
}
//原始功能的实现
public class ConcreteComponent implements Component{
	@Override
	public void operation() {
		System.out.println("拍照");
	}
}
//定义装饰器
public abstract class Decorator implements Component{
	protected Component component;
	public Decorator(Component component){
		this.component = component;
	}
}

//装饰器附加功能
class ConreteDecorator extends Decorator{

	public ConreteDecorator(Component component) {
		super(component);
	}

	@Override
	public void operation() {
		System.out.println("美颜");
		super.component.operation();
	}
}
//装饰器附加功能2
class ConreteDecorator1 extends Decorator{

	public ConreteDecorator1(Component component) {
		super(component);
	}

	@Override
	public void operation() {
		System.out.println("滤镜");
		super.component.operation();
	}
}

测试:

public class Test {
	public static void main(String[] args) {
		Component component = new ConreteDecorator1(new ConreteDecorator(new ConcreteComponent()));
		component.operation();
	}
}

应用场景
扩展一个类的功能或给一个类添加附加职责
优点:
1.不改变原有对象的情况下给一个对象扩展功能
2.使用不同的组合可以实现不同的效果
3.符合开闭原则

策略模式

定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式的变 化独立于算法的使用者。
比如说开发一个植物大战僵尸的游戏,定义一些僵尸,每种僵尸的类型、外观、移动、攻击等等有所不同。
比如第一版本 可能只有两种类型僵尸:普通僵尸和旗手僵尸 他们的外观不同、其他的移动和攻击相同
如果用传统代码编写 如下

//定义僵尸的抽象父类
public abstract class AbstractZombie {
	//外观不同 定义为抽象方法
	public abstract void display();
	//其他方式相同 定义为普通方法
	public void move(){
		System.out.println("一步一步移动");
	}
	public void attack(){
		System.out.println("咬");
	}
}
//定义僵尸
public class NormalZombie extends AbstractZombie{
	@Override
	public void display() {
		System.out.println("我是普通僵尸");
	}
}

class FlagZombie extends AbstractZombie{

	@Override
	public void display() {
		System.out.println("我是旗手僵尸");
	}
}

测试:

public class Test {
	public static void main(String[] args) {
		AbstractZombie zombie = new NormalZombie();
		AbstractZombie zombie1 = new FlagZombie();
		zombie.display();
		zombie.move();
		zombie.attack();
		System.out.println("---------------");
		zombie1.display();
		zombie1.move();
		zombie1.attack();

	}
}

在这里插入图片描述
后续随着业务发展,需要定义其他僵尸,比如定义大头僵尸,移动和以前相同,但是攻击是头撞

class BigHeadZombie extends AbstractZombie{
	@Override
	public void display() {
		System.out.println("我是大头僵尸");
	}
	@Override
	public void attack() {
		System.out.println("头撞");
	}
}

后续又定义了其他僵尸,攻击还是头撞,但是移动变了

class XxxZombie extends BigHeadZombie{
	@Override
	public void move() {
		System.out.println("跳着舞移动");
	}
	@Override
	public void display() {
		System.out.println("我是其他僵尸");
	}

}

这样随着业务的发展,继承越来越多,代码越来越复杂,维护管理都变得复杂。
那么使用策略模式进行改进。
首先把稳定的部分抽象出来,像移动、攻击、外观。每种僵尸都有这三种行为

//定义公用行为的策略接口
public interface Moveable {
	void move();
}

interface Attackable{
	void attack();
}
//移动的具体实现策略
public class StepByStepMove implements Moveable{
	@Override
	public void move() {
		System.out.println("一步一步移动");
	}
}

class DancingMove implements Moveable{
	@Override
	public void move() {
		System.out.println("跳着舞移动");
	}
}

//攻击策略
public class ComAttack implements Attackable{
	@Override
	public void attack() {
		System.out.println("咬");
	}
}

class HitAttack implements Attackable{
	@Override
	public void attack() {
		System.out.println("打");
	}
}

//定义僵尸抽象父类
public abstract class Zombie {
	protected abstract void display();
	protected Moveable moveable;
	protected Attackable attackable;
	abstract void move();
	abstract void attack();

	//构造方法 传入不同的策略
	public Zombie(Moveable moveable, Attackable attackable) {
		this.moveable = moveable;
		this.attackable = attackable;
	}

	//set get方法随时修改策略
	public Moveable getMoveable() {
		return moveable;
	}

	public void setMoveable(Moveable moveable) {
		this.moveable = moveable;
	}

	public Attackable getAttackable() {
		return attackable;
	}

	public void setAttackable(Attackable attackable) {
		this.attackable = attackable;
	}
}

public class NormalZombie extends Zombie{
	public NormalZombie(){
		super(new StepByStepMove(),new ComAttack());
	}
	public NormalZombie(Moveable moveable, Attackable attackable) {
		super(moveable, attackable);
	}
	@Override
	protected void display() {
		System.out.println("我是普通僵尸");
	}
	@Override
	void move() {
		super.moveable.move();
	}
	@Override
	void attack() {
		super.attackable.attack();
	}
}

public class FlagZombie extends Zombie{
	public FlagZombie(){
		super(new StepByStepMove(),new ComAttack());
	}
	public FlagZombie(Moveable moveable, Attackable attackable) {
		super(moveable, attackable);
	}
	@Override
	protected void display() {
		System.out.println("我是旗手僵尸");
	}
	@Override
	void move() {
		super.moveable.move();
	}
	@Override
	void attack() {
		super.attackable.attack();
	}
}

测试:

public class Test {
	public static void main(String[] args) {
		Zombie zombie = new NormalZombie();
		zombie.display();
		zombie.move();
		zombie.attack();
		//当想要修改攻击方式 只需要传入不同的攻击策略即可 不需要要修改代码
		zombie.setAttackable(new HitAttack());
		zombie.attack();

	}
}

当后续僵尸有不同的移动、攻击 只需要传入不同的移动、攻击策略,不需要修改实体类的代码,所有的僵尸类型都只继承了相同的抽象父类。维护简单

应用场景
1.当你有很多类似的类,但它们执行某些行为的方式不同时,请使用此 策略。
2.使用该模式将类的业务逻辑与算法的实现细节隔离开来,这些算法在 逻辑上下文中可能不那么重要。
3.当你的类具有大量的条件运算符,并且在同一算法的不同变体之间切 换时,请使用此模式

优点
1.可以将算法的实现细节与使用它的代码隔离开来。
2.符合开闭原则

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值