常用设计模式之工厂模式
常用设计模式之工厂模式
写作原由:
最近打算深入底层的去研究一下spring,spring第一重点是springIoc,底层原理是工厂模式+反射。那就先复习一下工厂设计模式吧,之前有学习过工厂模式,没有写笔记。现在你问我还记得多少?我只能回答还记得有这个模式
概念:
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
简单工厂模式:
interface IFruit{
public void eat(); //吃水果
}
class Apple implements IFruit{
public void eat(){
System.out.println("削皮吃苹果!");
}
}
class Orange implements IFruit{
public void eat(){
System.out.println("剥皮吃橘子!");
}
}
public class Factory{
public static void main(String args[]){
IFruit fruit = new Apple();
//削皮吃苹果!
fruit.eat();
}
}
简单说明:创建一个接口和多个类,这几个类对接口的eat()方法进行重写(实话说,我不知道这和当初学习多态的例子有啥不一样)
方法工厂模式:
ProjectFactory.java
public interface ProjectFactory {
Project getname();
}
BlueFactory.java(ConcreteFactory1)
public class BlueFactory implements ProjectFactory{
@Override
public Project getname() {
// TODO Auto-generated method stub
return new Bluepen();
}
}
RedFactory.java(ConcreteFactory2)
public class RedFactory implements ProjectFactory{
@Override
public Project getname() {
// TODO Auto-generated method stub
return new redPen();
}
}
Project.java(产品类)
public interface Project {
void name();
}
Bluepen.java(ConcreteProject1)
public class Bluepen implements Project{
@Override
public void name() {
// TODO Auto-generated method stub
System.out.println("这是一个蓝色的笔");
}
}
RedFactory.java(ConcreteProject2)
public class RedFactory implements ProjectFactory{
@Override
public Project getname() {
// TODO Auto-generated method stub
return new redPen();
}
}
测试类
public class Client {
public static void main(String[] args) {
Project pen = new RedFactory().getname();
pen.name();
Project pen1 = new BlueFactory().getname();
pen1.name();
}
}
运行结果:
简要总结:
简单工厂和工厂方法模式的不同在于前者生成产生产品的行为封装在一个方法中,根据参数的类型进行实例化,同时不存在抽象接口。而后者则增加了抽象工厂,通过实现不同的工厂方法来创建不同的产品,一个方法通常对应一个产品,这种方式相较于前者扩展性更高,在需求增加时完全符合开闭原则和依赖倒置原则
抽象工厂模式:
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
代码结构:
animalFactory.java(抽象动物工厂)
public interface animalFactory {
animal getLittle();
animal getBig();
}
catFactory.java(猫咪具体工厂)
public class catFactory implements animalFactory {
@Override
public animal getLittle(){
return new littleCat();
}
@Override
public animal getBig(){
return new bigCat();
}
}
dogFactory.java(狗子具体工厂)
public class dogFactory implements animalFactory {
@Override
public animal getLittle() {
return new littleDog();
}
@Override
public animal getBig() {
return new bigDog();
}
}
业务实现接口
//业务实现
public interface animal {
void saying();
}
cat.java(抽象喵咪种类)
public abstract class cat implements animal {
public abstract void saying();
}
bigCat.java(具体的一只大橘猫)
public class bigCat extends cat {
@Override
public void saying(){
System.out.println("一只大橘猫");
}
}
littleCat.java(具体的一只小茶杯猫)
public class littleCat extends cat {
@Override
public void saying(){
System.out.println("一只小茶杯猫");
}
}
dog.java(抽象狗子种类)
public abstract class dog implements animal {
public abstract void saying();
}
bigDog.java(具体的一只大金毛)
public class bigDog extends dog {
@Override
public void saying(){
System.out.println("一只大金毛");
}
}
littleDog.java(具体的一只小泰迪)
public class littleDog extends dog {
@Override
public void saying(){
System.out.println("一只小泰迪");
}
}
测试类:
public class test {
public static void main(String[] args) {
animalFactory cat = new catFactory();
animal big = cat.getBig();
big.saying();
animalFactory dog = new dogFactory();
animal little=dog.getLittle();
little.saying();
}
}
运行结果:
总结:
抽象工厂模式是工厂方法模式的升级版,后者面向单个产品,而前者面向的的是一个产品族。根据官方定义:为创建一组相关/互相依赖的对象提供一个接口而无需指定它们的具体类。比如一个汽车工厂要生成骑车,而每种汽车都有车门、车轮胎等一系列产品,这意味着每增加一款汽车就需要增加一个新的工厂来提供新产品的实现。这时候就可以使用抽象工厂模式来进行设计。抽象工厂模式适用于一系列产品族。
优点:
- 抽象厂模式将产品族的依赖与约束关系放到抽象工厂中,便于管理。
- 职责解耦,用户不需要关心一堆自己不关心的细节,由抽象厂来负责组件的创建
- 切换产品族容易,只需要增加一个具体工厂实现,客户端选择另-个套餐就可以了
缺点:
- 抽象工厂模式类增加的速度很快,有一个产品族就需要增加一一个具体工厂实现,比较繁琐
- 产品族难以扩展产品。当产品族中增加一个产品时,抽象工厂接口中需要增加一个函数,对应的所有具体工厂实现都需要修改,修改放大严重。
- 抽象厂并未完全屏蔽创建细节,给出的都是组件。对于这种情况可以结合工厂模式或简单工厂模式-起使用。
使用场景:
大家应该已经发现了,其实抽象工厂模式如果只有一个组件的话,其实是退化到工厂方法模式,也就是没有了产品族的概念,只剩一一个产品了,因此简单工厂,厂方法,抽象工厂这三者之间是有内在联系的,区别只产品的复杂度。抽象工厂的本质是选择产品族,因此大家可以根据这个特征来识别是否可以应用抽象厂。