**
设计模式之工厂模式
**
定义
Define an interface for creating an object,but let subclasses decide which class to instantiate
(定义一个用于创建对象的接口,让之类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。)
通用图解
产品抽象类Product.class
public abstract class Product {
public void method1(){
System.out.println("method1");
}
public abstract void method2();
}
具体产品类ConcretrProduct.class
public class ConcreteProduct extends Product {
@Override
public void method2() {
System.out.println("method2");
}
}
创造抽象类Creator.class
public abstract class Creator {
public abstract <T extends Product> T creatorProduct(Class<T> tClass);
}
创造工厂类
public class ConcreteCreator extends Creator{
@Override
public <T extends Product> T creatorProduct(Class<T> tClass) {
Product product = null;
try {
product = (T)Class.forName(tClass.getName()).newInstance();
}catch (Exception e){
System.out.print("创造失败");
}
return (T) product;
}
}
工厂模式优点
- 首先,良好分封装性,代码结构清晰。一个对象创建是有约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不需要知道创造者对象的辛苦过程,降低模块间的耦合。
- 其实,工厂方法模式的扩展性非常优秀。在添加产品类的情况下,只需适当的修改具体工厂类或扩展一个工厂类,就可以完成“拥抱变化”。
- 再次,屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
- 最后,工厂方法模式是经典的解耦框架。高层模块值需要知道产品的抽象类,其它的实现类都不需要关心,符合迪米特法则,我不需要的就不要去交流,也符合依赖倒置原则,只依赖品类的抽象,当然也符合理氏替换原则,使用产品子类替换产品父类,没问题!
经典实例,女娲造人
首先创建一个人类的总称接口类Human.class,方便后期的人种类继承其共性
public interface Human {
//每个人类都有自己的肤色
public void getColor();
//人类会说话
public void talk();
}
随后创建人种类BlackHuman.class,YellowHuman.class,WhiteHuman.class
public class BlackHuman implements Human {
@Override
public void getColor() {
System.out.println("黑色皮肤");
}
@Override
public void talk() {
System.out.println("Hellow 我是黑种人,我来自阿根廷");
}
}
public class YellowHuman implements Human {
@Override
public void getColor() {
System.out.println("黄色皮肤");
}
@Override
public void talk() {
System.out.println("Hellow 我是黄种人,我来自中国");
}
}
public class WhiteHuman implements Human {
@Override
public void getColor() {
System.out.println("白色皮肤");
}
@Override
public void talk() {
System.out.println("Hellow 我是白种人,我来自美国");
}
}
人种类创建好之后,我们在创建制作的抽象工具
public abstract class AbstractHumanFactory {
public abstract <T extends Human> T createHumane(Class<T> c);
}
之后,我们建一个工厂,利用这个工具来生产人类
public class HumanFactory extends AbstractHumanFactory{
@Override
public <T extends Human> T createHumane(Class<T> c) {
Human human = null;
try {
human = (T)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("人种创建失败");
}
return (T) human;
}
}
最后,万事俱备只欠东风了,这女娲来到了工厂中,利用工具开始造人了
public class NvWa {
@Test
public void test() {
//声明造人工具
AbstractHumanFactory factory = new HumanFactory();
System.out.println("开始造人");
//创建一个Class数组,把需要创建的人种存放进去
Class[] classes = new Class[]{WhiteHuman.class,BlackHuman.class,YellowHuman.class};
//通过foreach快速遍历制造各种人类
for (Class c:classes) {
Human humane = factory.createHumane(c);
humane.getColor();
humane.talk();
}
}
}
女娲进去有一段时间了,这我们来看看女娲造人的结果如何
女娲已经造化人了,你也来造造试试