设计模式之简单工厂模式与策略模式

一、简单工厂模式

概述:定义一个工厂类,它可以根据参数的不同返回不同的实例
类型:创建型-----通俗理解就是创建出一个对象的类型,该类型一定会创建出对象的
注意点:被创建的实例通常都具有共同的父类
做法
【1】定义一个抽象的对象
【2】定义抽象对象的具体实现子类
【3】定义一个创建对象的工厂

1】定义一个抽象的对象
//汽车:抽象产品
public abstract class Car {
    public String getCarName();
}2】定义抽象对象的具体实现子类
//奔驰:具体产品
public class BenCar extends Car {
    public String getCarName() {
    	return "奔驰";
    }
}
//宝马:具体产品
public class BaoCar extends Car {
    public String getCarName() {
    	return "宝马";
    }
}3】定义一个创建对象的工厂
public class CarFactory {
	// 入参的设计,可以搭配枚举来实现,会更加符合代码规范和业务理解
	public static Car getCar(String name) {
		if (object.equals("bao", name) {
			return new BaoCar();
		}
		if (object.equals("ben", name) {
			return new BenCar();
		}
		return null;
	}
}

【使用】
class Client {
    public static void main(String args[]) {
       // 重点(目的是为了获取一个对象,使用父类进行承接)
       Car car = CarFactory.getCar("bao");
       car.getCarName();
		
		Car car = CarFactory.getCar("ben");
       car.getCarName();
    }
}

个人的一些理解
【1】简单工厂模式,就如名字一样,只是一个工厂,用来生产一些东西的,至于拿到了这些东西要干什么,工厂就不管了,它只管生产东西(如:刀具厂,它负责生产它能生产的刀,至于拿到刀的人是切菜还是砍骨头,它就不管了)
【2】这些带工厂两字的工厂模式,感觉更多可能是强调子类实现父类这一思想,然后在获取结果的时候,使用父类来进行承接,也就是会出现向上转型,由于所有的子类都可以转成父类,因此使用的时候只需用父类就可以了,从而达到灵活使用;至于怎么去获取结果,方式可能有多种(如,上面那种简单的,在springboot项目中搭配依赖注入来实现注入到一个map中,然后再根据入参来获取、传入class使用反射来创建等等)
【3】这种工厂类型的模式,看着很简单,可能会觉得没有什么用,但是这具体还是要看业务呀,有用没用要看业务场景的(如:如果获取对象的参数由调用方可理解为前端传的话,那么这种方式就感觉很合适了,无论什么参数,拿到的对象都向上转型,直接使用父类进行调用了)
优点和缺点
【1】优点是能够灵活使用,方便扩展
【2】缺点嘛会造成很多子类,但是一定程度上可以忽略这个

二、策略模式

定义:定义一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化
通俗理解
【1】定义一系列算法就是有多种处理方式多种解决方案的意思,先把不同的解决方法实现,然后根据具体的情况选用不同的解决方法
【2】策略就是方法,办法,方针,计谋差不多的意思,策略模式就如把三十六计汇聚成一本书,一块研究管理,不然的话如此多的策略,打起仗来临时抱佛脚也不知道该去哪里抱啊
【3】策略模式就是把策略归置好,并且通过一个集中的环境去读取后使用。例如三十六计,就是把三十六中计谋集中归置到书本(集中的环境)中,代后人调阅,也不用管后人到底是古代人,还是现代人,还是中国人,还是外国人
行为型模式:类和对象如何交互,及划分责任和算法
注意点:一系列的具体算法通常都具有共同的父类,利用父类达到灵活调用
做法:
【1】定义一个抽象策略接口
【2】实现抽象策略接口来定义具体的策略
【3】定义一个执行者即上下文Context

1】定义一个抽象策略接口
public interface IEncryptStrategy {
	/**
	 * 对一个数字进行加密
	 */
	public double encrypt(double input);
}2】实现抽象策略接口来定义具体的策略
public class AddEncryptStrategy implements IEncryptStrategy {
	/**
	 * 将原来的值先+1,再加3,再+2,如此复杂的加密算法,一般人想不到哈
	 */
	@Override
	public double encrypt(double input) {
		return input + 1 + 3 + 2;
	}
}
public class MultiplyEncryptStrategy implements IEncryptStrategy {
	/**
	 * 乘法加密——为高端加密算法代言
	 */
	@Override
	public double encrypt(double input) {
		return input * 10;
	}
}3】定义一个执行者(上下文环境)
public class EncryptContext {
	/**
	 * 可保存任意策略
	 */
	private IEncryptStrategy strategy;

	public EncryptContext(IEncryptStrategy strategy) {
		this.strategy = strategy;
	}

	/**
	 * 调用保存的策略
	 */
	public double encrypt(double input) {
		return strategy.encrypt(input);
	}
}

【使用】
/**
 * 常规调用实例
 */
public class NormalUseStrategy {
	public static void main(String[] args) {
		EncryptContext context = new EncryptContext(new AddEncryptStrategy());
		System.out.println("加法策略:" + context.encrypt(1));
		context = new EncryptContext(new MultiplyEncryptStrategy());
		System.out.println("乘法策略:" + context.encrypt(1));
	}
}

个人理解感觉策略模式更多的是倾向于行为或方法的多样性,感觉强调的是某种行为或方法的多种形式;在业务上,如果某种行为出现多样性的时候,我觉得就可以使用策略模式了(比如买车这个行为,可以买奔驰、买宝马、买保时捷;无论买啥,最后抽象说法买的就是车);一定一定要注意,是一种行为,有多样性的时候

三、简单工厂和策略模式的相同和不同点

相同点
【1】代码实现方式很相似,都是子类实现父类,使用父类来达到灵活使用
【2】思想基本一样,都是子类实现父类这种多实现思想

不同点
【1】注重点不同,工厂模式注重获取对象,而策略模式注重的是获取对象的行为,调用对象的行为,后者比较关注实现细节
【2】两者的使用场景关注点不太一样,工厂模式是关注对象的创建,而策略模式,关注的是行为的多样性

一些理解
【1】我们去了一个咖啡厅,想喝一杯咖啡,
策略模式的咖啡厅会说:想喝卡布奇诺还是拿铁,自己调好咖啡和奶的比例拿给他,他帮你在咖啡机上磨好装杯子里给你
工厂模式的咖啡厅会说:跟他说要卡布奇诺还是拿铁就行,你不需要关心咖啡豆的比例和制作过程,他帮你做好装杯子里给你
【2】工厂相当于黑盒子,策略相当于白盒子

四、SpringBoot中用简单工厂搭配策略模式

做法
【1】定义一个抽策略接口
【2】实现抽象策略接口来定义具体的策略
【3】定义一个执行者即上下文Context(这里用法会不同)
【4】在Context中注入具体策略到Map中即把所有策略存储到Context
【5】使用的时候,传入对应策略的key和数据即可

1】定义一个抽象策略接口
public interface IEncryptStrategy {
	/**
	 * 对一个数字进行加密
	 */
	public double encrypt(double input);

	// 唯一标识
	public String getUniqueSign();
}2】实现抽象策略接口来定义具体的策略
public class AddEncryptStrategy implements IEncryptStrategy {
	/**
	 * 将原来的值先+1,再加3,再+2,如此复杂的加密算法,一般人想不到哈
	 */
	@Override
	public double encrypt(double input) {
		return input + 1 + 3 + 2;
	}

	// 唯一标识
	@Override
	public String getUniqueSign() {
		return "add";
	}
}
public class MultiplyEncryptStrategy implements IEncryptStrategy {
	/**
	 * 乘法加密——为高端加密算法代言
	 */
	@Override
	public double encrypt(double input) {
		return input * 10;
	}

	// 唯一标识
	@Override
	public String getUniqueSign() {
		return "multiplication";
	}
}3】定义一个执行者即上下文Context
public class EncryptContext {
	/**
	 * 可保存任意策略
	 */
	private Map<String, IEncryptStrategy> strategyMap = new HashMap<>();

	@PostConstruct
	public void init() {
		Map<String, IEncryptStrategy> beanMap = applicationContext.getBeansOfType(IEncryptStrategy.class);
		beanMap.values().forEach(strategy -> strategyMap.put(strategy.getUniqueSign(), strategy));
	}

	/**
	 * 调用策略
	 */
	public double encrypt(double input, String uniqueSign) {
		IEncryptStrategy strategy = strategyMap.get(uniqueSign);
		return strategy.encrypt(input);
	}
}

【使用】
public class NormalUseStrategy {
	public static void main(String[] args) {
		EncryptContext context = new EncryptContext();
		
		System.out.println("加法策略:" + context.encrypt(1, "add"));
		
		System.out.println("乘法策略:" + context.encrypt(1, "multiplication"));
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值