简单工厂
定义
简单工厂模式(Simple Factory Pattern)因为内部使用静态方法根据不同参数构造不同产品对象实例,也称静态工厂方法模式。
在简单工厂模式中,可以根据参数的不同返回不同实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
简单地说,一个工厂类 XxxFactory,里面有一个静态方法,根据我们不同的参数,返回不同的派生自同一个父类(或实现同一接口)的实例对象
demo
public class SimpleFactoryPattern {
public static void main(String[] args) {
Animal animal = AnimalFactory.createAnimal("0");
animal.name();
animal = AnimalFactory.createAnimal("1");
animal.name();
}
}
interface Animal {
void name();
}
class Dog implements Animal {
@Override
public void name() {
System.out.println("I'm dog.");
}
}
class Cat implements Animal {
@Override
public void name() {
System.out.println("I'm cat.");
}
}
class AnimalFactory {
public static Animal createAnimal(String type) {
if ("0".equals(type)) {
return new Dog();
} else if ("1".equals(type)) {
return new Cat();
}
return null;
}
}
优点
1)实现起来非常简单,也充分利用了多态机制
2)解耦(使调用端不再创建对象,而是交给工厂去创建),并且对内部实现屏蔽(调用端不知道具体实现)
缺点
违反开闭原则(对扩展开放,对修改关闭),如果有一个新的对象要添加,那么就要修改工厂
工厂方法
定义
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
demo
public class Demo {
public static void main(String[] args) {
AnimalFactory animalFactory = new DogFactory();
Animal animal = animalFactory.createAnimal();
animal.name();
animalFactory = new CatFactory();
animal = animalFactory.createAnimal();
animal.name();
}
}
interface Animal {
void name();
}
class Dog implements Animal {
@Override
public void name() {
System.out.println("I'Demo dog.");
}
}
class Cat implements Animal {
@Override
public void name() {
System.out.println("I'Demo cat.");
}
}
interface AnimalFactory {
Animal createAnimal();
}
class DogFactory implements AnimalFactory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
class CatFactory implements AnimalFactory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
优点
1)用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
2)在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
缺点
1)每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
适用场景
1)当一个类不知道它所需要创建的对象的类的时候
2)当一个类希望又它的子类来指定它创建的对象的时候
3)当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
案例
Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口,他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean
BeanFactory接口包含了getBean方法
Object getBean(String name):返回Sprin容器中id为name的Bean实例。
调用者只需使用getBean()方法即可获得指定Bean的引用,无须关心Bean的实例化过程。即Bean实例的创建过程完全透明。
在使用BeanFactory接口时,一般都是使用这个实现类:org.springframework.beans.factory.xml.XmlBeanFactory。然而ApplicationContext作为BeanFactory的子接口,使用它作为Spring容器会更加方便。它的实现类有:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。
抽象工厂
定义
提供了一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
public class Demo {
public static void main(String[] args) {
AnimalFactory animalFactory = new SparrowFactory();
Species species = animalFactory.createSpecies();
species.name();
LifeStyle lifeStyle = animalFactory.createLifeStyle();
lifeStyle.style();
}
}
// 生活方式
interface LifeStyle {
void style();
}
// 水里生活
class Water implements LifeStyle {
@Override
public void style() {
System.out.println("生活在水里");
}
}
// 陆地生活
class Terrestrial implements LifeStyle {
@Override
public void style() {
System.out.println("陆地生活");
}
}
// 物种
interface Species {
void name();
}
class Bird implements Species {
@Override
public void name() {
System.out.println("我是鸟类!");
}
}
class Fish implements Species {
@Override
public void name() {
System.out.println("我是鱼类!");
}
}
// 动物工厂
interface AnimalFactory {
LifeStyle createLifeStyle();
Species createSpecies();
}
// 麻雀
class SparrowFactory implements AnimalFactory{
@Override
public LifeStyle createLifeStyle() {
return new Terrestrial();
}
@Override
public Species createSpecies() {
return new Bird();
}
}
// 鲤鱼
class CarpFactory implements AnimalFactory{
@Override
public LifeStyle createLifeStyle() {
return new Water();
}
@Override
public Species createSpecies() {
return new Fish();
}
}
优点:
1)具备和工厂方法模式一样的优点
2)当增加一个新的产品族时不需要修改原代码,满足开闭原则
3)可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
缺点
1)难以支持新种类的产品,支持新种类的产品需要拓展工厂接口,这将涉及抽象工厂及其所有子类的
适用场景
1)当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
2)系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
3)系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。