文章目录
简单工厂模式(Simple Factory Pattern)
介绍
简单工厂模式其实并不属于GoF23种经典设计模式,它是一个常用的编程习惯。能根据不同的参数返回不同类的实例。
3种角色
- 抽象产品:定义产品的规范,描述产品的主要特性和功能。
- 具体产品:实现or继承抽象产品的子类。
- 具体工厂:提供创建产品的方法,通过调用这个来获得产品。
代码示例
题目一:使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,请实现该场景。
Person类(抽象产品):
public interface Person {
public void create();
}
Man类(具体产品1):
public class Man implements Person{
@Override
public void create() {
System.out.println("成功创造了男人...");
}
}
Woman类(具体产品2):
public class Women implements Person{
@Override
public void create() {
System.out.println("成功创建了女人...");
}
}
Nvwa类(具体工厂):
public class Nvwa {
public Person getPerson(String person1) throws Exception
{
if (person1.equalsIgnoreCase("M")){
return new Man();
} else if (person1.equalsIgnoreCase("W")){
return new Women();
} else {
throw new Exception("对不起,暂时无法创造该人。");
}
}
}
测试代码:
public class Test {
public static void main(String[] args) throws Exception {
Person person;
String person1 = "W";
person = Nvwa.getPerson(person1);
person.create();
}
}
题目二:在上述基础上,现需要增加一个新的Robot类,如果传入参数R,则返回一个Robot对象,对代码进行修改并注意女娲的变化。
新增Robot类(具体产品3):
public class Robot implements Person{
@Override
public void create() {
System.out.println("成功创造了机器人...");
}
}
修改Nvwa类(具体工厂):
public class Nvwa {
public Person getPerson(String person1) throws Exception
{
if (person1.equalsIgnoreCase("M")){
return new Man();
} else if (person1.equalsIgnoreCase("W")){
return new Women();
} else if (person1.equalsIgnoreCase("R")){
return new Robot();
} else {
throw new Exception("对不起,暂时无法创造该人。");
}
}
}
总结
- 应用场景:当使用者知道工厂需要的传入参数,并且对工厂如何生产出产品的逻辑并不关心。
- 优点:降低耦合度(将使用者和生产着隔离)。
- 缺点:每新增一个新的产品对象,就需要对工厂类的代码进行一次修改,这违反了设计模式中的“开闭原则”(题目二) 1。
静态工厂模式(Static Factory Pattern)
将工厂类中的创建对象的功能定义为静态的,这个就是静态工厂模式,它也不是23种设计模式中的。
public class Nvwa {
public static Person getPerson(String person1) throws Exception
{
if (person1.equalsIgnoreCase("M")){
return new Man();
} else if (person1.equalsIgnoreCase("W")){
return new Women();
} else if (person1.equalsIgnoreCase("R")){
return new Robot();
} else {
throw new Exception("对不起,暂时无法创造该人。");
}
}
}
工厂方法模式(Factory Method Pattern)
介绍
为了解决简单工厂模式的这个缺点,引入:工厂方法模式。工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor),工厂方法模式主要是对“工厂”的封装,提供一个创建者的接口,将产品实例化的步骤延迟到工厂的子类完成,让工厂的子类决定需要创建什么产品。遵循了"开闭原则"。
4种角色
- 抽象工厂:只提供创建产品的方法。
- 具体工厂:实现抽象工厂的方法,创建具体产品。
- 抽象产品:定义产品的规范。
- 具体产品:实现或继承抽象产品,由具体工厂进行生产,
与具体工厂一一对应
。
代码示例(沿用上述问题)
问题一:
/**
* 抽象工厂
**/
public interface NvwaFactory {
Person getPerson();
}
/**
* 具体工厂
*
* 抽象产品为Person,具体产品为Man和Women
* 这种工厂模式可以通过不同的具体工厂创建出不同的具体产品
**/
public class ManFactory implements NvwaFactory{
@Override
public Person getPerson() {
return new Man();
}
}
public class WomenFactory implements NvwaFactory{
@Override
public Person getPerson() {
return new Women();
}
}
测试代码:
public class Test{
public static void main(String[] args) {
new ManFactory().getPerson().create();
new WomenFactory().getPerson().create();
}
}
问题二:
只需要新增Robot类和RobotFactory就可以了。
通过上述例子,我们需要创建哪个产品,不再是靠外界传入参数决定,而是取决于抽象工厂使用的是具体哪个实现类。这种基于多态性设计的模式,使得产品的实例化延迟到具体子类之中,通过替换不同的实现子类就能达到新增和切换产品的目的。
总结
- 优点:在获取对象时只需要知道具体工厂的名称就可以得到对应的对象,无须知道具体创建过程;在系统增加新的类时只需要添加对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
- 缺点:每增加一个类就要增加一个对应的具体工厂类,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
抽象工厂模式(Abstract Factory Pattern)
介绍
4种角色
- 抽象工厂:
- 具体工厂:
- 抽象产品:
- 具体产品:
代码示例
总结
- 优点:
- 缺点:
开闭原则:即“开放-闭合原则”,软件架构应该设计成对于修改来说,代码实体是关闭的,而对于扩展来说,代码实体则是开放的。通俗一点讲,开闭原则是鼓励通过“新增”来代替“变化”。鼓励设计者将业务逻辑抽象化,将逻辑的本质设计成抽象类或者接口,逻辑的具体实践操作设计成具体实现类。 ↩︎