Java设计模式——工厂设计模式

Java设计模式——工厂设计模式

前言

  在了解工厂设计模式前,先要对"产品",“产品组”,“工厂”,OCP(开闭原则),这几个看似很专业的名词进行一定的了解,我将会使用一个小例子贯穿整个工厂设计模式。
  对"产品",“产品组”,"工厂"的初步理解

举个栗子
  若你作为一名消费者(客户)想要购买一台笔记本电脑,此时
    工厂:微软、联想、华硕…(电脑制造厂商)
    产品:内存、显卡、CPU中的某一种
    产品组:电脑制造厂商想要组装一台可以使用的电脑,该电脑不会由某一件"产品"所组成,而是由产品组(相互之间存在依赖关系的产品的集合)所构成,在这个例子中,产品组就是组装一台电脑所需要的所有零件的集合

  对OCP(开闭)原则的初步理解

在设计和代码编写时应当所遵循的开闭原则:在现有代码上以最小的改动为代价来进行新功能的添加,尽可能的在添加新功能的时候不去改动现有的代码——对扩展开放,对修改关闭

一、工厂模式的引入

举个栗子

	// 定义一个Computer接口,并定义一个简单的printComputer方法用于输出该电脑的名称
	interface Computer {
	    void printComputer();
	}
	
	// 定义Macbook类实现Computer接口
	class MacbookProComputer implements Computer {
	    public void printComputer() {
	        System.out.println("This is a MacbookPro");
	    }
	}

	// 定义SurfaceBook类实现Computer接口
	class SurfaceBookComputer implements Computer {
	    public void printComputer() {
	        System.out.println("This is a SurfaceBook");
	    }
	}
	
	public class Client {
		// 将形参设置为接口,而实参设置为接口的具体实现类
	    public void buyComputer(Computer computer) {
	        computer.printComputer();
	    }
	
	    public static void main(String[] args) {
	        Client client = new Client();
	        // 不同品牌的电脑需要修改这行代码new的对象
	        client.buyComputer(new MacbookProComputer());
	    }
	}
  如果是上面这种情况,如果此时用户需要买一台华硕电脑,那么除了需要在服务端中添加一个HuaShuoComputer类去实现Computer接口之外,还必须修改客户端的代码,将new MacbookProComputer()改为new HuaShuoComputer()
  当产品发布或产品更新后,客户端的代码尽可能的不要改动(添加新功能时),这样的改动严重违反了OCP开闭原则。因此,引入三种工厂模式来解决此类问题。

二、简单工厂模式(没有产品组并且产品个数较少)

  1、定义:专门定义一个类(第三方类),用来创建其他类实例(解耦<提取出来>,将客户端创建对象的操作解耦到外部第三方类中),被创建的实例通常都具有共同的父类。
  2、实例描述:客户需要购买什么样的电脑,只需要创建一个电脑工厂,并提供对应电脑的编号即可(真正电脑对象的产生将在电脑工厂中进行)
	import java.util.Scanner;
	
	interface Computer{
	    void buyComputer();
	}
	
	class MacBookPro implements Computer{
	    public void buyComputer(){
	        System.out.println("This is MacBookPro");
	    }
	}
	
	class AlienBook implements Computer{
	    public void buyComputer(){
	        System.out.println("This is AlienBook");
	    }
	}

	/**
	 * 创建电脑对应的简单工厂,在该工厂内通过客户端输入的电脑编号,进行对应产品类的实例化
	 */
	class ComputerFactory{
	    public Computer buyComputer(String type){
	        if(type.equals("mac")){
	            return new MacBookPro();
	        }else if(type.equals("alien")){
	            return new AlienBook();
	        }
	        return null;
	    }
	}
	
	
	public class FactoryModelTest{
	 
	    public static void main(String[] args) {
	        Scanner scanner = new Scanner(System.in);
	        System.out.println("Please input your choose:");
	        String type = scanner.nextLine();
	        ComputerFactory computerFactory = new ComputerFactory();
	        Computer computer = computerFactory.buyComputer(type);
	        if(computer!=null){
	            computer.buyComputer();
	        }else{
	            System.out.println("No such computer");
	        }
	        
	    }
	}
  运行结果:

在这里插入图片描述

  3、组成:
    ①一个抽象产品类(Computer)
    ②多个具体产品类(MacBookPro,AlienBook…<Computer的实现类>)
    ③一个工厂类(ComputerFactory)
  4、应用场景:没有产品组且产品个数较少(eg:Spring-BeanFactory)

三、工厂方法模式

  1、定义:将简单工厂再次升级,定义一个用来创建对象的接口,让子类决定实例化哪一个工厂。(创建工厂的接口,并创建多个工厂类实现该工厂接口,并在每个工厂类中实例化产品对象,每一个工厂类对应一个产品)
  2、实例描述:创建一个电脑工厂的接口,并创建多个工厂类实现该电脑工厂接口,在这些工厂类中分别实例化该工厂所对应的那个产品。客户端会根据具体使用的哪个工厂类而知道创建的什么产品。
	/**
	 * 创建产品接口
	 */
	interface Computer{
	    void buyComputer();
	}
	
	class MacbookPro implements Computer{
	    public void buyComputer(){
	        System.out.println("This is a mac");
	    }
	}
	
	class AlienBook implements Computer{
	    public void buyComputer(){
	        System.out.println("This is a alien");
	    }
	}
	
	/**
	 * 创建工厂接口,并在该接口中定义方法用于实例化产品,将实例化产品延迟到子类中
	 */
	interface ComputerFactory{
	    Computer createComputer();
	}
	
	/**
	 * 在工厂接口的实现类中对产品进行实例化
	 */
	class AppleFactory implements ComputerFactory{
	    public Computer createComputer(){
	        return new MacbookPro();
	    }
	}
	
	class MsFactory implements ComputerFactory{
	    public Computer createComputer(){
	        return new AlienBook();
	    }
	}
	
	public class FactoryModelTest2{
	    public static void main(String[] args) {
	        ComputerFactory computerFactory = new MsFactory();
	        Computer computer = computerFactory.createComputer();
	        computer.buyComputer();
	    }
	}
  运行结果:

在这里插入图片描述

  3、组成:
    ①一个抽象产品类(Computer)
    ②多个具体产品类(MacBookPro,AlienBook…<Computer的实现类>)
    ③一个抽象工厂(ComputerFactory)
    ④多个具体工厂(AppleFactory,MsFactory…<ComputerFactory的实现类>)
  4、应用:将产品的实例化延迟到工厂的子类中进行,可根据工厂的类型判断出产品的类型(eg:Spring-FactoryBean)

四、抽象工厂模式

  1、定义:提供一个创建一系列相关或相互依赖对象的接口(抽象工厂,多条产品线),而无需指定它们具体的类。(在工厂方法模式的基础上多加几条产品线,将工厂方法模式的一个工厂对应一个产品,转换为一个工厂对应一个产品组<多个产品的组合>)
  2、实例描述:在电脑工厂接口中添加选择操作系统的方法,此时的操作系统+电脑品牌构成了一个产品组,而电脑工厂接口,电脑品牌接口,操作系统接口在定义的时候只需要知道它们彼此的关系即可,而不需要知道这些接口具体是怎么实现的。
	/**
	 * 创建产品Computer(电脑类型)接口
	 */
	interface Computer{
	    void buyComputer();
	}
	
	class MacbookPro implements Computer{
	    public void buyComputer(){
	        System.out.println("This is a mac");
	    }
	}
	
	class AlienBook implements Computer{
	    public void buyComputer(){
	        System.out.println("This is a alien");
	    }
	}
	
	/**
	 * 创建产品OperatingSystem(操作系统)接口
	 */
	interface OperatingSystem{
	    void printSystem();
	}
	
	class MacOsSytem implements OperatingSystem{
	
	    @Override
	    public void printSystem() {
	        System.out.println("This is a Mac Os");
	    }
	}
	
	class Windows10System implements OperatingSystem{
	
	    @Override
	    public void printSystem() {
	        System.out.println("This is a windows 10");
	    }
	}
	
	/**
	 * 创建工厂接口,并在该接口中定义方法用于实例化产品,将实例化产品延迟到子类中
	 * 一个工厂——>多个产品(产品组)
	 */
	interface ComputerFactory{
	    Computer createComputer();
	    OperatingSystem createSystem();
	}
	
	/**
	 * 在工厂接口的实现类中对多个产品(产品组——相互之间存在关系的产品)进行实例化
	 */
	class AppleFactory implements ComputerFactory{
	    public Computer createComputer(){
	        return new MacbookPro();
	    }
	
	    @Override
	    public OperatingSystem createSystem() {
	        return new MacOsSytem();
	    }
	}
	
	class MsFactory implements ComputerFactory{
	    public Computer createComputer(){
	        return new AlienBook();
	    }
	
	    @Override
	    public OperatingSystem createSystem() {
	        return new Windows10System();
	    }
	}
	public class FactoryModelTest3 {
	
	    
	
	    public static void main(String[] args) {
	        // 一个工厂接口的具体实现类对应一个产品组
	        ComputerFactory computerFactory = new MsFactory();
	        Computer computer = computerFactory.createComputer();
	        OperatingSystem operatingSystem = computerFactory.createSystem();
	        computer.buyComputer();
	        operatingSystem.printSystem();
	    }
	}
  运行结果:

在这里插入图片描述

  3、组成:
    ①多个抽象产品类(Computer,OperatingSystem…)
    ②每一个抽象产品类都对应了多个具体产品类(Computer的实现类,OperatingSystem的实现类…<抽象产品类的多个实现类>)
    ③一个抽象工厂(ComputerFactory)
    ④多个具体工厂(AppleFactory,MsFactory…<ComputerFactory的实现类>)
  4、应用:一个工厂对应多个产品(产品组),定义工厂接口与多个产品接口之间的逻辑关系即可,不需要关注这些接口的具体实现。(Collection中的iterator方法<集合类的迭代器>)

五、总结

  1、简单工厂模式:将创建对象的逻辑判断放在了工厂类中(第三方类),客户并不知道具体有哪些类,但违背了开闭原则(在新增具体类的时候,必须修改工厂类),客户端需要什么商品只需要修改工厂类的调用而不需要修改客户端,降低了客户端与具体商品的依赖。
  2、工厂方法模式:设置工厂接口,将实例化产品的操作延迟到工厂接口的子类中实行,符合开闭原则,但在客户端中必须创建对应的工厂接口的子类实例。横向扩展很方便,若有新的产品要生产,只需要创建对应的产品类与工厂类即可,不需要修改原有的代码。
  3、抽象工厂模式:进一步的扩展了工厂方法模式,使得一个工厂对应多个产品(产品组),扩展非常灵活。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值