设计模式:工厂模式
定义
工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个子类的实例化延迟到其子类
Factory Pattern : Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses
优点
- 良好的封装性,代码结构清晰
- 优秀的扩展性
- 屏蔽产品类
- 典型的解耦框架:
- 迪米特法则:高层只需要知道产品的抽象类,其他的实现都不用关心
- 依赖倒置:只依赖产品类的抽象
- 里氏替换,使用产品子类替换产品父类
使用场景
主要用于需要灵活可扩展的框架时
具体实现
- 通用工厂模式实现
//工厂需要制造的产品总接口
public interface Human {
public void getColor();
public void talk();
}
//每个产品的具体实现
public class BlackHuman implements Human {
public void getColor() {
System.out.println("My color is black!");
}
public void talk() {
System.out.println("Hi, I am black human!");
}
}
public class WhiteHuman implements Human {
public void getColor() {
System.out.println("My color is white!");
}
public void talk() {
System.out.println("Hi, I am white human!");
}
}
public class YellowHuman implements Human {
public void getColor() {
System.out.println("My color is yellow!");
}
public void talk() {
System.out.println("Hi, I am yellow human!");
}
}
//抽象产品创建工厂
public abstract class AbstractHumanFactory {
public abstract <T extends Human> T createHuman(Class<T> c);
}
//产品创建工厂
public class HumanFactory extends AbstractHumanFactory {
@Override
public <T extends Human> T createHuman(Class<T> c) {
Human human = null;
try {
human = (T) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("Error!");
}
return (T) human;
}
}
//场景类(调用)
public static void main(String[] args) {
AbstractHumanFactory ahf = new HumanFactory();
Human h1 = ahf.createHuman(BlackHuman.class);
h1.talk();
h1.getColor();
Human h2 = ahf.createHuman(WhiteHuman.class);
h2.talk();
h2.getColor();
Human h3 = ahf.createHuman(YellowHuman.class);
h3.talk();
h3.getColor();
}
- 工厂扩展模式1:简单工厂模式
public class SimpleFactory {
public static void main(String[] args) {
Human h1 = HumanFactory.createHuman(BlackHuman.class);
h1.talk();
h1.getColor();
Human h2 = HumanFactory.createHuman(WhiteHuman.class);
h2.talk();
h2.getColor();
Human h3 = HumanFactory.createHuman(YellowHuman.class);
h3.talk();
h3.getColor();
}
}
//工厂类
class HumanFactory {
public static <T extends Human> T createHuman(Class<T> c) {
Human human = null;
try {
human = (T) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
System.out.println("Error!");
}
return (T) human;
}
}
个人理解:简化了的工厂模式,舍弃了抽象工厂类,直接用静态方法的方式构建工厂方法。代码结构简化了,但同时扩展性降低。一种较常用的变种模式
工厂扩展模式2:多个工厂类
public class MultiFactories {
public static void main(String[] args) {
Human whiteHuman = (new WhiteHumanFactory()).createHuman();
Human blackHuman = (new BlackHumanFactory()).createHuman();
Human yellowHuman = (new YellowHumanFactory()).createHuman();
}
}
abstract class AbstractHumanFactory {
public abstract Human createHuman();
}
class WhiteHumanFactory extends AbstractHumanFactory {
@Override
public Human createHuman() {
return new WhiteHuman();
}
}
class BlackHumanFactory extends AbstractHumanFactory {
@Override
public Human createHuman() {
return new BlackHuman();
}
}
class YellowHumanFactory extends AbstractHumanFactory {
@Override
public Human createHuman() {
return new YellowHuman();
}
}
个人理解:当工厂方法本身非常复杂的时候,可以使用这个模式。缺点是一个产品类就要对应一个工厂类,增加了扩展的难度
- 工厂扩展模式3:单例工厂模式
public class SingletonFactory {
private static Singleton singleton;
static {
try {
Class c1 = Class.forName(Singleton.class.getName());
//获得无参构造
Constructor constructor = c1.getDeclaredConstructor();
//设置无参构造可访问
constructor.setAccessible(true);
//产生一个实例对象
singleton = (Singleton) constructor.newInstance();
} catch (Exception e) {
}
}
public static Singleton getSingleton() {
return singleton;
}
}
class Singleton {
private Singleton() {
}
}
个人理解:这也就是之前单例模式中提到的用反射实现在其他类中对仅拥有private构造函数的类进行初始化的方法。本人实际暂时还不能理解这种模式在什么场景下适用,今后如果有进一步体悟会来补全此处
抽象工厂模式
最后简单提一下抽象工厂模式
抽象工厂模式:为创建一组相关或相互依赖的对象提供一个借口,而且无需指定他们的具体类
Abstract Factory Pattern:Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
暂时不开单章说明这个模式了,因为个人没有遇到过类似的场景,理解实在不深。大体来说就是把工厂方法的职能更加细化,分到各个车间生产线级别。同时这些车间生产线生产的产品存在一定的关联性(产品族)
参考内容:《设计模式之禅》秦小波