工厂方法模式(Factory Method Pattern):创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
抽象工厂模式(Abstract Factory Pattern):是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的创建者(Creator) 里加代码,又要在具体的里面加代码。
抽象工厂模式通常适用于以下场景:
1.当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
2.系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。
3.系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
实现:
1.工厂方法模式:
下面来看下工厂方法模式的组成:
1) 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2) 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3) 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4) 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
1.抽象工厂角色
/**
*
* @ClassName: Provider
* @Description:抽象工厂角色
* @author: ljx
* @date: 2018年12月19日 上午10:32:45
*/
public interface Provider{
public Sender produce();
}
2.两个具体工厂角色
/**
*
* @ClassName: SendMailFactory
* @Description: 具体工厂角色
* @author: ljx
* @date: 2018年12月19日 上午10:33:14
*/
public class SendMailFactory implements Provider {
@Override
public Sender produce() {
return new MailSender();
}
}
/**
*
* @ClassName: SendSmsFactory
* @Description: 具体工厂角色
* @author: ljx
* @date: 2018年12月19日 上午10:33:26
*/
public class SendSmsFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
3.抽象产品角色
/**
*
* @ClassName: Sender
* @Description: 发送接口
* @author: ljx
* @date: 2018年12月18日 下午3:47:52
*/
public interface Sender {
public void Send();
}
4.两个具体产品角色
/**
*
* @ClassName: MailSender
* @Description: 邮件
* @author: ljx
* @date: 2018年12月19日 上午10:32:13
*/
public class MailSender implements Sender{
public void Send(){
System.out.println("this is mail");
}
}
/**
*
* @ClassName: SmsSender
* @Description: sms
* @author: ljx
* @date: 2018年12月19日 上午10:32:31
*/
public class SmsSender implements Sender {
@Override
public void Send() {
System.out.println("this is sms!");
}
}
测试:
public class Test {
public static void main(String[] args) {
Provider sendSms = new SendSmsFactory();
Provider sendMail = new SendMailFactory();
Sender sms = sendSms.produce();
Sender mail = sendMail.produce();
sms.Send();
mail.Send();
}
}
结果:this is sms!
this is mail
2.抽象工厂模式
先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族。
使用抽象工厂模式还要满足以下条件:
1) 系统中有多个产品族,而系统一次只可能消费其中一族产品。
2) 同属于同一个产品族的产品以其使用。
两个抽象产品接口:
/**
*
* @ClassName: SportsCarA
* @Description: 跑车接口
* @author: ljx
* @date: 2018年12月19日 下午1:39:18
*/
public interface SportsCarA {
public void car();
}
/**
*
* @ClassName: SedanCarB
* @Description: 小桥车接口
* @author: ljx
* @date: 2018年12月19日 下午1:41:11
*/
public interface SedanCarB {
public void car();
}
两个产品实现类:
/**
*
* @ClassName: SportsMashaladiA1
* @Description: 跑车实现类
* @author: ljx
* @date: 2018年12月19日 下午1:46:40
*/
public class SportsMashaladiA1 implements SportsCarA {
@Override
public void car() {
System.out.println("我是玛莎拉蒂跑 车");
}
}
/**
*
* @ClassName: SportsBaomaA2
* @Description: 跑车实现类
* @author: ljx
* @date: 2018年12月19日 下午1:47:36
*/
public class SportsBaomaA2 implements SportsCarA {
@Override
public void car() {
System.out.println("我是宝马跑 车");
}
}
/**
*
* @ClassName: SedanBaomaB1
* @Description: 小轿车实现类
* @author: ljx
* @date: 2018年12月19日 下午1:43:05
*/
public class SedanBaomaB1 implements SedanCarB {
@Override
public void car() {
System.out.println("我是宝马小轿车");
}
}
/**
*
* @ClassName: SedanMashaladiB2
* @Description: 小桥车实现类
* @author: ljx
* @date: 2018年12月19日 下午1:45:13
*/
public class SedanMashaladiB2 implements SedanCarB {
@Override
public void car() {
System.out.println("我是玛莎拉蒂小轿车");
}
}
抽象工厂角色
/**
*
* @ClassName: Creator
* @Description: 抽象工厂角色
* @author: ljx
* @date: 2018年12月19日 下午1:50:03
*/
public interface Creator {
public SportsCarA createSportsCar();
public SedanCarB createSedanCar();
}
两个具体工厂角色
/**
*
* @ClassName: MashaladiCreator
* @Description: 具体工厂角色:玛莎拉蒂工厂
* @author: ljx
* @date: 2018年12月19日 下午2:04:52
*/
public class MashaladiCreator implements Creator{
@Override
public SportsCarA createSportsCar() {
return new SportsMashaladiA1();
}
@Override
public SedanCarB createSedanCar() {
return new SedanMashaladiB2();
}
}
/**
*
* @ClassName: SportsCreator
* @Description: 具体工厂角色:宝马工厂
* @author: ljx
* @date: 2018年12月19日 下午2:00:09
*/
public class BaomaCreator implements Creator {
@Override
public SportsCarA createSportsCar() {
return new SportsBaomaA2();
}
@Override
public SedanCarB createSedanCar() {
return new SedanBaomaB1();
}
}
测试:
/**
*
* @ClassName: Test
* @Description: 测试
* @author: ljx
* @date: 2018年12月19日 下午2:06:59
*/
public class Test {
public static void main(String[] args) {
Creator creator = new MashaladiCreator();//玛莎拉蒂
Creator creator2 = new BaomaCreator();//宝马
SedanCarB mashaladiB = creator.createSedanCar();//玛莎拉蒂轿车
mashaladiB.car();
SedanCarB baomaB = creator2.createSedanCar();//宝马轿车
baomaB.car();
SportsCarA mashaladiA = creator.createSportsCar();//玛莎拉蒂跑车
mashaladiA.car();
SportsCarA baomaA = creator2.createSportsCar();//宝马轿车
baomaA.car();
}
}
结果:我是玛莎离地小轿车
我是宝马小轿车
我是玛莎拉蒂跑车
我是宝马跑车
正如上面的例子,这两个模式区别在于需要创建对象的复杂程度上,工厂方法模式创建的是一个对象,当需要新的产品接口2时,那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现。
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个(产品族)。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例(一对一),而抽象工厂模式可以创建多个具体产品类的实例(一对多)。
......,欢迎指正!