工厂模式(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();
}
}
本程序非常简单就是通过接口的子类为接口对象实例化,但是本操作存在什么样的问题呢?
之前一直在强调,主方法或者是主类是一个客户端,客户端的操作应该越简单越好。但是在现在的程序之中,有一个最大的问题:客户端之中,一个接口和一个固定的子类绑在一起了。
在本程序之中,最大的问题在于耦合上,发现在主方法之中一个接口和一个子类紧密耦合在一起,这种方法比较直接,可以简单的理解为:A→B,但是这种紧密的方式不方便于维护,所以后来使用了A→B→C,中间经历了一个过渡,这样一来B去改变,C去改变,但是A不需要改变,就好比JAVA的JVM一样:程序→JVM→操作系统。
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();
}
}
这个时候发现客户端不在和一个具体的子类耦合在一起了,就算以后增加了新的子类,那么也只需要修改Factory类即可。
消费者不关心它所要创建对象的类(产品类)的时候。
消费者知道它所要创建对象的类(产品类),但不关心如何创建的时候。
例如:hibernate里通过sessionFactory创建session、通过代理方式生成ws客户端时,通过工厂构建报文中格式化数据的对象。
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
抽象工厂模式与工厂方法模式的区别
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。
在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。.
如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。
Factory.java(抽象工厂)
public interface Factory {
PhoneProject projectPhone();
LaptopProject projectLaptop();
}
HuaWeiFactory.java(华为具体工厂)
public class HuaWeiFactory implements Factory{
@Override
public PhoneProject projectPhone() {
// TODO Auto-generated method stub
return new HuaWeiPhone();
}
@Override
public LaptopProject projectLaptop() {
// TODO Auto-generated method stub
return new HuaWeiLaptop();
}
}
XiaomiFactory.java(小米具体工厂)
public class XiaomiFactory implements Factory{
@Override
public PhoneProject projectPhone() {
// TODO Auto-generated method stub
return new XiaomiPhone();
}
@Override
public LaptopProject projectLaptop() {
// TODO Auto-generated method stub
return new XiaomiLaptop();
}
}
LaptopProject.java(笔记本产品)
public interface LaptopProject {
void getId();
void printInfo();
}
HuaWeiLaptop.java(华为笔记本)
public class HuaWeiLaptop implements LaptopProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号"+123);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产了华为电脑");
}
}
XiaomiLaptop.java(小米笔记本)
public class XiaomiLaptop implements LaptopProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号"+213);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产小米电脑");
}
}
PhoneProject.java(手机产品)
public interface PhoneProject {
void getId();
void printInfo();
}
HuaWeiPhone.java(华为手机)
public class HuaWeiPhone implements PhoneProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号:"+123412);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产华为手机");
}
}
XiaomiPhone.java(小米手机)
public class XiaomiPhone implements PhoneProject{
@Override
public void getId() {
// TODO Auto-generated method stub
System.out.println("编号:"+123412);
}
@Override
public void printInfo() {
// TODO Auto-generated method stub
System.out.println("生产了小米手机!!");
}
}
测试类:
public class Client {
public static void main(String[] args) {
PhoneProject huawei = new HuaWeiFactory().projectPhone();
huawei.printInfo();
huawei.getId();
PhoneProject xiaomi = new XiaomiFactory().projectPhone();
xiaomi.printInfo();
LaptopProject huawei1 = new HuaWeiFactory().projectLaptop();
huawei1.printInfo();
}
}
抽象工厂模式是工厂方法模式的升级版,后者面向单个产品,而前者面向的的是一个产品族。根据官方定义:为创建一组相关/互相依赖的对象提供一个接口而无需指定它们的具体类。
比如一个汽车工厂要生成骑车,而每种汽车都有车门、车轮胎等一系列产品,这意味着每增加一款汽车就需要增加一个新的工厂来提供新产品的实现。这时候就可以使用抽象工厂模式来进行设计。抽象工厂模式适用于一系列产品族。
大家应该已经发现了,其实抽象工厂模式如果只有一个组件的话,其实是退化到工厂方法模式,也就是没有了产品族的概念,只剩一一个产品了,因此简单工厂,厂方法,抽象工厂这三者之间是有内在联系的,区别只产品的复杂度。抽象工厂的本质是选择产品族,因此大家可以根据这个特征来识别是否可以应用抽象厂。