一、简单工厂模式(Simple Factory)
1,UML图
工厂类(creator)角色:担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体Java类实现。
抽象产品(Product)角色:担任这个角色的类是由工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个Java接口或者Java抽象类实现。
具体产品(Concrete Product)角色:工厂方法模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体Java类实现。
2, 模式说明
简单工厂模式也称静态工厂模式,是由一个工厂类根据传入的参量决定创建出哪一种产品类的实例,是不同的工厂方法模式的一个特殊实现。
3,模式示例代码
package com.maohao.build.factory.simple;
public interface Fruit {
public void grow();
}
package com.maohao.build.factory.simple;
public class Apple implements Fruit {
public Apple() {
grow();
}
@Override
public void grow() {
System.out.println("an apple grows");
}
}
package com.maohao.build.factory.simple;
public class Orange implements Fruit {
public Orange() {
grow();
}
@Override
public void grow() {
System.out.println("an orange grows");
}
}
package com.maohao.build.factory.simple;
public class SimpleFactory {
public static Fruit growFruit(String choose) {
if(choose.equalsIgnoreCase("apple")) {
return new Apple();
} else if(choose.equalsIgnoreCase("orange")) {
return new Orange();
} else {
return null;
}
}
public static void main(String[] args) {
SimpleFactory.growFruit("apple");
SimpleFactory.growFruit("orange");
}
}
4,模式优缺点
优点:简单、客户端直接负责“消费”产品,实现了责任的分割;
缺点:(1)工厂类集中了所有产品的逻辑,若他不能工作了,整个产品就完了;
(2)当产品类有不同的接口种类时,工厂类需要判断什么时候创建某种产品。这种对时机的判断和对哪一种具体产品的决断逻辑混合在一起,使得系统在将来进行功能扩展时较为困难;(对“开闭”原则支持不够)
(3)工厂方法是静态,使用无法由子类继承,因此工厂角色无法形成基于继承的等级结构;
5,与其他模式比较
单例模式:单例模式使用了简单工厂模式,但两者有不同,单例模式要求构造子是私有的;
6,模式应用
DateFormat::getDateInstance()
二、工厂方法模式(Factory Method)
1,UML图
抽象工厂(Creator)角色:担任这个角色的是工厂方法模式的核心,它是与应用程序无关的。任何模式中创建对象的工厂类必须实现这个接口。在上面的系统中,这个角色由Java接口Creator扮演;在实际的系统中,这个角色也常使用抽象Java类实现。
具体工厂(Concrete Creator)角色:担任这个角色的是实现了抽象工厂接口的具体Java类。具体工厂角色含有与应用密切相关的逻辑,并且受到应用程序的调用以创建产品对象。在本系统中给出了两个这样的角色,也就是具体Java类ConcreteCreator1和ConcreteCreator2。
抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在本系统中,这个角色由Java接口Product扮演;在实际的系统中,这个角色也常常使用抽象Java类实现。
具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所声明的接口。工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。在本系统中,这个角色由具体Java类ConcreteProduct1和ConcreteProduct2扮演,它们都实现了Java接口Product。
2,模式说明
简单工厂模式使用了多态性,保持了简单工厂模式的优点,而且克服了它的缺点。首先,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出
具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。这种进一步抽象化的结果,使这种工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品,这一特点无疑使得工厂模式具有超过简单工厂模式的优越性。
3,模式示例代码
package com.maohao.build.factory.method;
import com.maohao.build.factory.simple.Fruit;
public interface FruitGardener {
public Fruit factory();
}
package com.maohao.build.factory.method;
import com.maohao.build.factory.simple.Apple;
import com.maohao.build.factory.simple.Fruit;
public class AppleGardener implements FruitGardener {
@Override
public Fruit factory() {
return new Apple();
}
}
package com.maohao.build.factory.method;
import com.maohao.build.factory.simple.Fruit;
import com.maohao.build.factory.simple.Orange;
public class OrangeGardener implements FruitGardener {
@Override
public Fruit factory() {
return new Orange();
}
}
package com.maohao.build.factory.method;
public class MethodFactory {
public static void main(String[] args) {
FruitGardener fg = new AppleGardener();
FruitGardener fg2 = new OrangeGardener();
fg.factory();
fg2.factory();
}
}
4,与其他模式比较
模版方法模式:(1)两个模式都是基于方法的,工厂方法模式是基于多态性的工厂方法的,而模版方法模式是基于模版方法和基本方法的
(2)两个模式都将具体工作交给子类。工厂方法模式将创建工作推延给子类,模版方法模式将剩余逻辑交给子类。
5,模式应用
(1)Java所有集合对象iterator()方法返回Iterator类
(2)List集合还有一个listIterator()方法,返回ListIterator对象
(3)URL类的openConnetion()返还一个URLConnection类型的对象
三、抽象工厂模式(Abstract Factory)
1, UML图
抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用Java接口或者抽象Java类实现,而所有的具体工厂类必须实现这个Java接口或继承这个抽象Java类;
具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。通过使用具体Java类实现这个角色。
抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用Java接口或者抽象Java类实现这一角色。
具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端需要的东西,其内部一定充满了应用系统的商业逻辑。通常使用具体Java类实现这个角色。
2,模式说明
抽象工厂模式是对象的创建模式,它是工厂模式的进一步推广。一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构。那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开来,可以引进抽象工厂模式。
这样的话,消费产品一主不需要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品。
GOF95指出,在以上情况下应当考虑使用抽象工厂模式:
一个系统不应当依赖于产品类实例如何被创建、组合和表达细节,这对于所有形态的工厂模式都是重要的;
这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品;
同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来;
系统提供一个产品类的库,所有的产品以同样的样品中出现,从而使客户端不依赖于实现。
3,模式示例代码
package com.maohao.build.factory.abstractFactory;
public interface Apple {
public void grow();
}
package com.maohao.build.factory.abstractFactory;
public interface Gardener {
public Apple createApple();
public Orange createOrange();
}
package com.maohao.build.factory.abstractFactory;
public interface Orange {
public void grow();
}
package com.maohao.build.factory.abstractFactory;
public class RedApple implements Apple {
@Override
public void grow() {
System.out.println("a red apple grows!");
}
}
package com.maohao.build.factory.abstractFactory;
public class RedGardener implements Gardener {
@Override
public Apple createApple() {
return new RedApple();
}
@Override
public Orange createOrange() {
return new RedOrange();
}
}
package com.maohao.build.factory.abstractFactory;
public class RedOrange implements Orange {
@Override
public void grow() {
System.out.println("a red orange grow!");
}
}
package com.maohao.build.factory.abstractFactory;
public class YellowApple implements Apple {
@Override
public void grow() {
System.out.println("a yellow apple grows!");
}
}
package com.maohao.build.factory.abstractFactory;
public class YellowGardener implements Gardener {
@Override
public Apple createApple() {
return new YellowApple();
}
@Override
public Orange createOrange() {
return new YellowOrange();
}
}
package com.maohao.build.factory.abstractFactory;
public class YellowOrange implements Orange {
@Override
public void grow() {
System.out.println("a yelloOrange grows!");
}
}