一、
制作一个抽象产品:螺丝
制作2个具体产品:8mm螺丝 和 6mm螺丝
使用简单工厂来实现这个场景,并且让客户端通过简单工厂来获取具体产品。
然后扩展一个7mm螺丝,你会发现这要修改简单工厂的代码。进而违反了开闭原则。
所以在使用工厂方法来重构一遍代码。保证7mm螺丝可以被顺利地扩展进来
简单工厂
/**
* @author 郑金冲
* @create 2020-05-29 20:29
* @Description 简单工厂 作业
* @Telephone 17805202282
* @Email xiaozhengjc@163.com
*/
public class Client {
public static void main(String[] args) {
Factory.getScrew("8毫米").screwInfourmation();
}
}
//产品基类: 螺丝
interface Screw {
public void screwInfourmation();
}
//具体产品类: 8毫米螺丝
class EightMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一个8毫米的螺丝啊。。。。");
}
}
//具体产品类: 6毫米螺丝
class SixMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一个6毫米的螺丝啊。。。。");
}
}
//工厂
class Factory {
public static Screw getScrew(String type) {
Screw screw = null;
switch (type) {
case "8毫米":
screw = new EightMillimeterScrew();
break;
case "6毫米":
screw = new SixMillimeterScrew();
break;
}
return screw;
}
}
工厂方法
/**
* @author 郑金冲
* @create 2020-05-29 20:29
* @Description 简单工厂 作业
* @Telephone 17805202282
* @Email xiaozhengjc@163.com
*/
public class Client2 {
public static void main(String[] args) {
SevenMillimeterScrewFactory obj = new SevenMillimeterScrewFactory();
obj.getScrew().screwInfourmation();
}
}
//产品基类: 螺丝
interface Screw {
public void screwInfourmation();
}
//具体产品类: 8毫米螺丝
class EightMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一个8毫米的螺丝啊。。。。");
}
}
//具体产品类: 7毫米螺丝
class SevenMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一个7毫米的螺丝啊。。。。");
}
}
//具体产品类: 6毫米螺丝
class SixMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一个6毫米的螺丝啊。。。。");
}
}
//螺丝工厂基类
interface ScrewFactory{
public Screw getScrew();
}
//8毫米螺丝工厂
class EightMillimeterScrewFactory implements ScrewFactory{
@Override
public Screw getScrew() {
return new EightMillimeterScrew();
}
}
//7毫米螺丝工厂
class SevenMillimeterScrewFactory implements ScrewFactory{
@Override
public Screw getScrew() {
return new SevenMillimeterScrew();
}
}
//6毫米螺丝工厂
class SixMillimeterScrewFactory implements ScrewFactory{
@Override
public Screw getScrew() {
return new SixMillimeterScrew();
}
}
二、
总结工厂以及原型设计模式,谈谈你们开发过程中使用使用各种框架,
见识各种源码,在哪些地方体现了工厂模式,原型模式。
答:
工厂模式:
工厂模式实际应用中可分为简单工厂,工厂方法,抽象工厂三类
简单工厂:
优点:
* 1:将具体产品的类型 从客户端端代码中解耦出来
* 2:服务端代码修改了具体的产品类名 客户端不知道,这便符合我们的 面向接口编程 的思想
* 这里的接口不单包括 interface 只要是下层给上层暴露出来的方法、类 都可认为是面向接口编程里的接口形式
缺点:
* 1:type 与具体产品映射关系
* 2:如果 具体产品非常大,简单工厂的代码会变得非常臃肿
* 3.扩展具体产品,势必会修改简单工厂的代码,违反了 开闭原则
* 4.始终丢失原始类数据
工厂方法:
优点:
* 1.具有简单工厂的优点 符合开闭原则
* 2.扩展了新产品,不需要修改作者原来的代码,新加一个工厂而已
缺点:
* 1.高耦合了,只知道具体工厂类名 才能修改相关具体产品
* 2.每增加一个产品等级 就要增加一个生产产品的工厂以及具体的产品类 和产品生产工厂
这样会 造成类的爆炸式增长增加了系统复杂度 增加了开销
* 3.一个具体工厂只能创建一个具体产品
* 4.设计太过复杂
*
* 规约:约定大于配置
* 工厂的名字 视为接口。作为作者,有责任和义务保证工厂的名字是趋向稳定的
抽象工厂:
优点:具备简单工厂和工厂方法的优点
* 1.抽象工厂减少了工厂类,无论有多少的产品等级,工厂就一套
* 疑问: 为啥具体产品要这样搭配?
* 抽象工厂中,可以生产多个产品,这些产品必须要有逻辑关系
* 产品簇 ,产品等级
缺点:
* 1.当产品等级发生变化,需要引起所有之前的工厂代码的修改违反了 开闭原则
结论:
* 产品等级比较固定,考虑抽象工厂
* 产品等级经常变化 不建议抽象工厂
* 产品等级少 建议工厂方法
spring bean的创建就是一个典型的工厂模式,我们无需创建Bean,Spring 的BeanFactory帮我们做到了,
我们只要在需要的地方通过依赖注入来获取需要的实例。
原型模式:
1.类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
2.通过new一个对象需要非常繁琐的数据准备或访问权限,可以使用原型模式。
3.一个对象需要提供给其他对象访问,而且各个调用者可能需要修改其值,可以考虑使用原型模式拷贝多个对象供调用者使 用, 即保护性拷贝