为了账号安全,请及时绑定邮箱和手机立即绑定

慕课网《模式的秘密之工厂模式》学习总结

标签:
Java

慕课网《模式的秘密之工厂模式》学习总结

时间:2017年08月27日星期日
说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com
教学源码:https://github.com/zccodere/study-imooc
学习源码:https://github.com/zccodere/study-imooc
第一章:工厂模式概述
1-1 工厂模式概述

什么是设计模式

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结

应用设计模式的好处

设计模式是优秀的使用案例
使用设计模式可提高代码的重用性
让代码更容易被他人理解
保证代码可靠性

重点内容

工厂模式的概念
工厂模式的意图
工厂模式的应用场景
工厂模式的设计思想
工厂模式的好处

工厂模式概念

实例化对象,用工厂方法代替new操作
工厂模式包括工厂方法模式和抽象工厂模式
抽象工厂模式是工厂方法模式的扩展

工厂模式的意图

定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化
工厂方法把实例化的工作推迟到子类中去实现

什么情况下适合工厂模式

有一组类似的对象需要创建
在编码时不能预见需要创建哪种类的实例
系统需要考虑扩展性,不应依赖于产品类实例如果被创建、组合和表达的细节

项目中的现状

在软件系统中经常面临着“对象”的创建工作,由于需求的变化,
这个对象可能随之也会发生变化,但它却拥有比较稳定的接口。
为此,我们需要提供一种封装机制来隔离出这个异变对象的变化,
从而保持系统中其他依赖该对象的对象不随着需求变化而变化。

基于项目现状将代码进行如下设计

尽量松耦合,一个对象的依赖对象的变化与本身无关
具体产品与客户端剥离,责任分割

工厂方法模式类图

图片描述

抽象工厂模式类图

图片描述

第二章:工厂模式应用
2-1 工厂模式应用

代码编写

1.编写HairInterface类

package com.myimooc.designpattern.c2factory.hair;

/**
 * @describe 发型接口
 * @author zc
 * @version 1.0 2017-08-27
 */
public interface HairInterface {

    /**
     * 画发型
     */
    void draw();

}

2.编写LeftHair类

package com.myimooc.designpattern.c2factory.hair;

/**
 * @describe 左偏分发型
 * @author zc
 * @version 1.0 2017-08-27
 */
public class LeftHair implements HairInterface {

    /**
     * 画一个左偏分发型
     */
    @Override
    public void draw() {
        System.out.println("左偏分发型");
    }
}

3.编写RightHair类

package com.myimooc.designpattern.c2factory.hair;

/**
 * @describe 右偏分发型
 * @author zc
 * @version 1.0 2017-08-27
 */
public class RightHair implements HairInterface {

    /**
     * 画一个右偏分发型
     */
    @Override
    public void draw() {
        System.out.println("右偏分发型");
    }

}

4.编写InHair类

package com.myimooc.designpattern.c2factory.hair;

/**
 * @describe 中偏分发型
 * @author zc
 * @version 1.0 2017-08-27
 */
public class InHair implements HairInterface{

    @Override
    public void draw() {
        System.out.println("中偏分发型");
    }
}

5.编写type.properties文件

left=com.myimooc.designpattern.c2factory.LeftHair
right=com.myimooc.designpattern.c2factory.RightHair
in=com.myimooc.designpattern.c2factory.InHair

6.编写PropertiesReader类

package com.myimooc.designpattern.c2factory.hair;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @describe properties文件读取类
 * @author zc
 * @version 1.0 2017-08-27
 */
public class PropertiesReader {

    public Map<String,String> getProperties(){
        Properties props = new Properties();
        Map<String,String> map = new HashMap<String,String>();
        try{
            InputStream in = getClass().getResourceAsStream("type.properties");
            props.load(in);
            @SuppressWarnings("unchecked")
            Enumeration<String> en = (Enumeration<String>) props.propertyNames();
            while (en.hasMoreElements()) {
                String key = en.nextElement();
                String property = props.getProperty(key);
                map.put(key, property);
            }
            in.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}

7.编写HairFactory类

package com.myimooc.designpattern.c2factory;

import java.util.Map;

import com.myimooc.designpattern.c2factory.hair.HairInterface;
import com.myimooc.designpattern.c2factory.hair.LeftHair;
import com.myimooc.designpattern.c2factory.hair.PropertiesReader;
import com.myimooc.designpattern.c2factory.hair.RightHair;

/**
 * @describe 发型工厂
 * @author zc
 * @version 1.0 2017-08-27
 */
public class HairFactory {

    /**
     * 根据类型来创建对象
     * @param key
     * @return
     */
    public HairInterface getHair(String key){
        if("left".equals(key)){
            return new LeftHair();
        }
        else if("right".equals(key)){
            return new RightHair();
        }
        return null;
    }

    /**
     * 根据类的名称来生产对象
     * @param className
     * @return
     */
    public HairInterface getHairByClass(String className){
        try {
            HairInterface hair = (HairInterface) Class.forName(className).newInstance();
            return hair;
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据类的名称来生产对象
     * @param className
     * @return
     */
    public HairInterface getHairByClassKey(String key){
        try {
            Map<String,String> map = new PropertiesReader().getProperties();
            HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance();
            return hair;
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

8.编写Test类

package com.myimooc.designpattern.c2factory;

import com.myimooc.designpattern.c2factory.hair.HairInterface;

/**
 * @describe 模拟客户端实现
 * @author zc
 * @version 1.0 2017-08-27
 */
public class Test {

    public static void main(String[] args) {

//        HairInterface left = new LeftHair();
//        left.draw();
//        
//        HairInterface right = new RightHair();
//        right.draw();

        HairFactory factory = new HairFactory();
//        HairInterface left = factory.getHair("left");
//        left.draw();

        HairInterface left = factory.getHairByClass("com.myimooc.designpattern.c2factory.LeftHair");
        left.draw();

//        HairInterface hair = factory.getHairByClassKey("in");
//        hair.draw();

    }
}
第三章:抽象工厂模式
3-1 抽象工厂模式

代码编写

1.编写Boy类

package com.myimooc.designpattern.c2factory.boy;

/**
 * @describe 男孩
 * @author zc
 * @version 1.0 2017-08-27
 */
public interface Boy {

    void drawMan();

}

2.编写HnBoy类

package com.myimooc.designpattern.c2factory.boy;

/**
 * @describe 新年系列的男孩
 * @author zc
 * @version 1.0 2017-08-27
 */
public class HnBoy implements Boy {

    @Override
    public void drawMan() {
        System.out.println("新年系列的男孩");
    }
}

3.编写McBoy类

package com.myimooc.designpattern.c2factory.boy;

/**
 * @describe 圣诞系列的男孩
 * @author zc
 * @version 1.0 2017-08-27
 */
public class McBoy implements Boy {

    @Override
    public void drawMan() {
        System.out.println("圣诞系列的男孩");
    }
}

4.编写Girl类

package com.myimooc.designpattern.c2factory.girl;

/**
 * @describe 女孩
 * @author zc
 * @version 1.0 2017-08-27
 */
public interface Girl {

    void drawWomen();

}

5.编写HnGril类

package com.myimooc.designpattern.c2factory.girl;

/**
 * @describe 新年系列的女孩
 * @author zc
 * @version 1.0 2017-08-27
 */
public class HnGril implements Girl {

    @Override
    public void drawWomen() {
        System.out.println("新年系列的女孩");
    }
}

6.编写McGril类

package com.myimooc.designpattern.c2factory.girl;

/**
 * @describe 圣诞系列的女孩
 * @author zc
 * @version 1.0 2017-08-27
 */
public class McGril implements Girl {

    @Override
    public void drawWomen() {
        System.out.println("圣诞系列的女孩");
    }
}

7.编写PersonFactory类

package com.myimooc.designpattern.c2factory;

import com.myimooc.designpattern.c2factory.boy.Boy;
import com.myimooc.designpattern.c2factory.girl.Girl;

/**
 * @describe 人物的实现接口
 * @author zc
 * @version 1.0 2017-08-27
 */
public interface PersonFactory {

    // 获取男孩接口
    Boy getBoy();

    // 获取女孩接口
    Girl getGirl();
}

8.编写HnFactory类

package com.myimooc.designpattern.c2factory;

import com.myimooc.designpattern.c2factory.boy.Boy;
import com.myimooc.designpattern.c2factory.boy.HnBoy;
import com.myimooc.designpattern.c2factory.girl.Girl;
import com.myimooc.designpattern.c2factory.girl.HnGril;

/**
 * @describe 新年系列加工厂
 * @author zc
 * @version 1.0 2017-08-27
 */
public class HnFactory implements PersonFactory {

    @Override
    public Boy getBoy() {
        return new HnBoy();
    }

    @Override
    public Girl getGirl() {
        return new HnGril();
    }
}

9.编写McFactory类

package com.myimooc.designpattern.c2factory;

import com.myimooc.designpattern.c2factory.boy.Boy;
import com.myimooc.designpattern.c2factory.boy.McBoy;
import com.myimooc.designpattern.c2factory.girl.Girl;
import com.myimooc.designpattern.c2factory.girl.McGril;

/**
 * @describe 圣诞系列加工厂
 * @author zc
 * @version 1.0 2017-08-27
 */
public class McFactory implements PersonFactory {

    @Override
    public Boy getBoy() {
        return new McBoy();
    }

    @Override
    public Girl getGirl() {
        return new McGril();
    }
}

10.修改Test类

package com.myimooc.designpattern.c2factory;

import com.myimooc.designpattern.c2factory.boy.Boy;
import com.myimooc.designpattern.c2factory.girl.Girl;
import com.myimooc.designpattern.c2factory.hair.HairInterface;

/**
 * @describe 模拟客户端实现
 * @author zc
 * @version 1.0 2017-08-27
 */
public class Test {

    public static void main(String[] args) {

//        HairInterface left = new LeftHair();
//        left.draw();
//        
//        HairInterface right = new RightHair();
//        right.draw();

        HairFactory factory = new HairFactory();
//        HairInterface left = factory.getHair("left");
//        left.draw();

        HairInterface left = factory.getHairByClass("com.myimooc.designpattern.c2factory.LeftHair");
        left.draw();

//        HairInterface hair = factory.getHairByClassKey("in");
//        hair.draw();

        testPerson();
    }

    public static void testPerson(){
        PersonFactory factory = new McFactory();
        Girl girl = factory.getGirl();
        girl.drawWomen();

        factory = new HnFactory();
        Boy boy = factory.getBoy();
        boy.drawMan();

    }
}
第四章:总结
4-1 总结

场景应用

图片描述

Spring BeanFactory

BeanFactory,作为Spring基础的IOC容器,是Spring的一个Bean工厂
如果单从工厂模式的角度思考,它就是用来“产生Bean”,然后提供给客户端

Bean的实例化过程如下

调用Bean的默认构造方法,或指定的构造方法,生成bean实例(暂称为instance1)
如果Bean的配置文件中注入了Bean属性值,则在instance1基础上进行属性注入形成instance2,这种注入是覆盖性的
如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法,来改变或操作instance2,得到instance3
如果Bean的配置文件中指定了init-method=”init”属性,则会调用指定的初始化方法,
则在instance3的基础上调用初始化方法init(),将对象最终初始化为instance4;当然,这个初始化的名字是任意的

工厂方法模式和抽象工厂模式对比

工厂模式是一种极端情况下的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广
工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构
工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类

工厂模式的实现帮助我们

系统可以在不修改具体工厂角色的情况下引进新的产品
客户端不必关系对象如何创建,明确了职责
更好的理解面向对象的原则,面向接口编程,而不要面向实现编程

工厂模式适用于哪些场景

一个系统应当不依赖于产品类实例被创立、组成和表示的细节。这对所有形态的工厂模式都是重要的
这个系统的产品有至少一个的产品族
同属于一个产品族的产品是设计成在一起使用的。这一约束必须得在系统的设计中体现出来
不同的产品以一系列的接口的面貌出现,从而使系统不依赖于接口实现的细节
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
138
获赞与收藏
532

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消