工厂类模式

工厂模式

理解:调用者不用去关心对象如何创建,调用工厂提供的方法就行了。

  • 举个粟子: 女祸造人的粟子 1 先定义一个human类,具有讲话和获取肤色的行为
  package com.tmq.designmodeldemo.factory.factorymethod;
/**
 * @Author tangmqb DCITS
 * @DATE 2020/7/23 19:05
 * @Version 1.0.0
 */
public interface Human {
    public void getColor();
    public void sayHello();
}

2 各类人

  package com.tmq.designmodeldemo.factory.factorymethod;

/**
 * @Author tangmqb DCITS
 * @DATE 2020/7/23 19:11
 * @Version 1.0.0
 */
public class YellowHuman implements Human {
    @Override
    public void getColor() {
        System.out.println("黄种人的皮肤是黄色的");
    }

    @Override
    public void sayHello() {
        System.out.println("黄种人讲中文:你好!");
    }
}

WhilteHuman、BlackHuman类似...

简单工厂

  • 理解 工厂没有子类,直接创建,简单粗暴,静态方法
package com.tmq.designmodeldemo.factory.simplefactory;

import com.tmq.designmodeldemo.factory.factorymethod.Human;

/**
 * 简单工厂方法
 * 只有一个工厂 不需要再工厂造(new)出来
 * 在实际项目中,采用该方法的案例还是比较多的,其缺点是工厂类的扩展比
 * 较困难,不符合开闭原则,但它仍然是一个非常实用的设计模式
 * @Author tangmqb DCITS
 * @DATE 2020/7/23 19:27
 * @Version 1.0.0
 */
public class SimpleHamanFactory {
    public static <T extends Human> T createHuman(Class<T> clzz) {
        Human human = null;
        try {
            human = (Human) Class.forName(clzz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T)human;
    }
}

工厂方法

  • 定义
    • 定义一个用于创建对象的接口,让子类决定实现哪一类。
  • 理解
    • 工厂方法与简单工厂的区别记住这句话就行了:工厂方法使一个类的实例化延迟到其子类。 非静态的创建方法

ps:这里使用的是反射的方式实现,看了一些其他的博客,有些是直接new出来的,这样不太好,实际工作中也是经常用反射的方式来实现工厂类的。

  • 抽象类,让子类去实现
package com.tmq.designmodeldemo.factory.factorymethod;

/**
 * 工厂方法
 * @Author tangmqb DCITS
 * @DATE 2020/7/23 19:13
 * @Version 1.0.0
 */
public abstract class AbstractHumanFactory {

    public  abstract  <T extends Human> T createHuman(Class<T> clzz);
}
  • 工厂子类(真正生产的工厂)
 package com.tmq.designmodeldemo.factory.factorymethod;

/**
 * 工作方法
 * @Author tangmqb DCITS
 * @DATE 2020/7/23 19:15
 * @Version 1.0.0
 */
public class HumanFactory extends AbstractHumanFactory {
    @Override
    public <T extends Human> T createHuman(Class<T> clzz) {
        Human human =null;
        try {
            human = (Human)Class.forName(clzz.getName()).newInstance();
        } catch (Exception e) {
            System.out.println("造人失败.......");
        }
        return (T)human;
    }
}

抽象工厂

  • 定义 为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们 的具体类。
  • 理解 让想创建的对象实现不同的功能组合。
  • 抽象出对象(Human)
  • 让对象有不同的实现(getColor talk getSex(不同))
  • 重新定义human类
public interface Human {
//每个人种都有相应的颜色
public void getColor();
//人类会说话
public void talk();
//每个人都有性别
public void getSex();
}
  • YellowHuman,相同的行为,抽象出来
ublic abstract class AbstractYellowHuman implements Human {
public void getColor(){
System.out.println("黄色人种的皮肤颜色是黄色的!");
}
public void talk() {
System.out.println("黄色人种会说话,一般说的都是双字节。");
}
}
  • 不同的性别,独立出来
public class FemaleYellowHuman extends AbstractYellowHuman {
//黄人女性
public void getSex() {
System.out.println("黄人女性");
}
}

public class MaleYellowHuman extends AbstractYellowHuman {
//黄人男性
public void getSex() {
System.out.println("黄人男性");
}
}
  • 抽象工厂
 public class NvWa {
public static void main(String[] args) {
//第一条生产线,男性生产线
HumanFactory maleHumanFactory = new MaleFactory();
//第二条生产线,女性生产线
HumanFactory femaleHumanFactory = new FemaleFactory();
//生产线建立完毕,开始生产人了:
Human maleYellowHuman = maleHumanFactory.createYellowHuman();
Human femaleYellowHuman = femaleHumanFactory.createYellowHuman();
System.out.println("---生产一个黄色女性---");
femaleYellowHuman.getColor();
femaleYellowHuman.talk();
femaleYellowHuman.getSex();
System.out.println("\n---生产一个黄色男性---");
maleYellowHuman.getColor();
maleYellowHuman.talk();
maleYellowHuman.getSex();
/*
* ......
* 后面继续创建
*/
}
}

工厂方法优点

首先,良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合。 最后,工厂方法模式是典型的解耦框架。高层模块值需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特法则,我不需要的就不要去交流;也符合依赖倒置原则,只依赖产品类的抽象;当然也符合里氏替换原则,使用产品子类替换产品父类,没问题!

end

评论