抽象工厂模式

工厂方法模式(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变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现。

工厂方法模式

一个抽象产品类,可以派生出多个具体产品类。

一个抽象工厂类,可以派生出多个具体工厂类。

每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式

多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。

一个抽象工厂类,可以派生出多个具体工厂类。

每个具体工厂类可以创建多个具体产品类的实例。

区别

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个(产品族)

工厂方法模式的具体工厂类只能创建一个具体产品类的实例(一对一),而抽象工厂模式可以创建多个具体产品类的实例(一对多)

......,欢迎指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值