1,工厂模式(Factory)
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。
- 案例
需求:一个披萨制作的项目,要求该项目易于扩展维护;
1、能够生产出美式披萨、中式披萨...
2、披萨制作过程包含原材料准备、烘培、切割、打包
3、可生成披萨订单
public interface Pizza {
void pre();
void bake();
void cut();
void box();
}
/**
* 中式披萨
*/
class ChinesePizza implements Pizza {
public ChinesePizza() {
this.pre();
this.bake();
this.cut();
this.box();
}
@Override
public void pre() {
System.out.println("中式披萨材料准备...");
}
@Override
public void bake() {
System.out.println("中式披萨烘培...");
}
@Override
public void cut() {
System.out.println("中式披萨的切片...");
}
@Override
public void box() {
System.out.println("中式披萨包装盒包装");
}
}
/**
* 美式披萨
*/
class AmericaPizza implements Pizza {
public AmericaPizza() {
this.pre();
this.bake();
this.cut();
this.box();
}
@Override
public void pre() {
System.out.println("美式 披萨材料准备...");
}
@Override
public void bake() {
System.out.println("美式 披萨烘培...");
}
@Override
public void cut() {
System.out.println("美式 披萨的切片...");
}
@Override
public void box() {
System.out.println("美式 披萨包装盒包装");
}
}
class JapanPizza implements Pizza {
public JapanPizza() {
this.pre();
this.bake();
this.cut();
this.box();
}
@Override
public void pre() {
System.out.println("日式 披萨材料准备...");
}
@Override
public void bake() {
System.out.println("日式 披萨烘培...");
}
@Override
public void cut() {
System.out.println("日式 披萨的切片...");
}
@Override
public void box() {
System.out.println("日式 披萨包装盒包装");
}
}
没使用
public class PizzaFactory {
public static Pizza createPizza(int no){
switch (no){
case 1:
return new ChinesePizza();
case 2:
return new AmericaPizza();
case 3:
return new JapanPizza();
}
return null;
}
}
public class Client {
public static void main(String[] args) {
Pizza chinaPizza = PizzaFactory.createPizza(1);
System.out.println("=============================");
Pizza americaPizza = PizzaFactory.createPizza(2);
System.out.println("=============================");
Pizza japanPizza = PizzaFactory.createPizza(3);
}
}
使用后(工厂类)
public class PizzaFactory {
public static Pizza createPizza(int no){
Pizza pizza = null;
switch (no){
case 1:
pizza = new ChinesePizza();
break;
case 2:
pizza = new AmericaPizza();
break;
case 3:
pizza = new JapanPizza();
break;
}
if (pizza == null){
System.out.println("没有此披萨订购服务");
}else {
pizza.pre();
pizza.bake();
pizza.cut();
pizza.box();
}
return pizza;
}
}
public class Client {
public static void main(String[] args) {
Pizza chinaPizza = PizzaFactory.createPizza(1);
System.out.println("=============================");
Pizza americaPizza = PizzaFactory.createPizza(2);
System.out.println("=============================");
Pizza japanPizza = PizzaFactory.createPizza(3);
System.out.println("=============================");
Pizza otherPizza = PizzaFactory.createPizza(4);
}
}
使用前后代码对比:
前者将对象初始化的工作交给了对象的构造函数完成;
后者将初始化的过程交给了工厂类完成;
这么做的好处在于解耦自身对象实例化和对象初始化动作,还有一个因素在于构造函数的初始化会影响到子类;
带入点:
Spring中的javabean是什么时候初始化的!是容器初始化时候还是工厂创建对象初始化?
总方法:
public class InstanceFactory {
public void init() {
System.out.println("初始化方法");
}
public void destroy() {
System.out.println("销毁方法");
}
public void service() {
System.out.println("业务方法");
}
}
总测试:
/**
* Bean的生命周期
单例对象
出生:当容器创建时对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡
总结:单例对象的生命周期和容器相同
多例对象
出生:当我们使用对象时Spring框架为我们创建
活着:对象只要是在使用过程中就一直活着
死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
*
* @author Administrator
*
*/
public class Demo2 {
// 单例对象与多例对象的初始化时间不一样 通过scope属性来演示
@Test
public void test1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
}
// 单例对象与多例对象的初始化时间不一样 通过scope属性来演示
@Test
public void test2() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
InstanceFactory i1 = (InstanceFactory) applicationContext.getBean("instanceFactory");
i1.service();
// scope="prototype",容器关闭不会自动销毁bean对象
applicationContext.close();
}
/**
* 说明了两点:
* scope的值对应的是两个工厂类,生产javabean的模式一样;
* 1.一个是单例一个是多例
* 2.一个是立即初始化,一个是使用初始化
* 反正要初始化一次,干脆把所有的初始化操作放到监听器里面去,提高系统应用的性能
* 多例本身会耗性能,那么就尽可能在使用的时候再去创造对象
*/
@Test
public void test3() {
// ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
Resource resource = new ClassPathResource("/spring-context.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource );
InstanceFactory i1 = (InstanceFactory) beanFactory.getBean("instanceFactory");
}
}
单例:容器中的对象默认初始化
配置文件:
测试:
// 单例对象与多例对象的初始化时间不一样 通过scope属性来演示
@Test
public void test1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
}
结果:
多例:使用对象的时候才初始化
如果加上 scope="prototype"
结果:
(工厂模式代替new的目的在于:实例化与初始化数据的解藕)
2.适配器模式(Adapter)
把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作(简单:将两种完全不同的事物联系到一起)
分为3种:
类适配器模式:Adapter 类,通过继承 source 类,实现 Destination 类接口,完成 source->Destination 的适配。
对象适配器模式: 将 Adapter 类作修改,不是继承 source 类,而是持有 source 类的实例,以解决兼容性的问题。 即:持有 source 类,实现 Destination 类接口,完成source->Destination 的适配
接口适配器模式:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求适用于一个接口不想使用其所有的方法的情况
实例 ( 接口适配器模式):
//(一个类)
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-22 15:51
*
* 220V的电压
*/
public class Voltage220V {
private double voltage;
public Voltage220V() {
this.voltage = 220;
}
public double getVoltage() {
return voltage;
}
public void setVoltage(double voltage) {
this.voltage = voltage;
}
}
//(一个接口)
/**
* 目标接口
*/
interface Voltage5V{
double getVoltage();
}
//(一个类且实现一个接口(上面那个))
/**
* 适配器:里面封装了source源到destination目标的过程
*/
class VoltageAdapter implements Voltage5V{
private Voltage220V voltage220V;
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
@Override
public double getVoltage() {
return voltage220V.getVoltage() / 40;
}
}
//(实现方法)
public class Phone {
// 充电
public void charge(Voltage5V voltage5V){
double voltage = voltage5V.getVoltage();
System.out.println("最终手机充电所用电压:" + voltage + "V");
}
}
//(测试方法)
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
// 已知有一个220V的电源,要用它给手机进行充电,我们只能将220V的电源进行处理后才能给手机充上电
// VoltageAdapter适配器对Voltage220V这个不能直接使用的电源适配后就可以使用了
phone.charge(new VoltageAdapter(new Voltage220V()));
}
}
注意事项和细节:
Adapter 模式最大的作用还是将原本不兼容的接口融合在一起工作