zoukankan      html  css  js  c++  java
  • Java设计模式 -- 简单工厂模式(SimpleFactory)

    一、什么是简单工厂模式

          简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

    二、模式中包含的角色及其职责

    1.工厂(Creator)角色 简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
    2.抽象(Product)角色 简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
    3.具体产品(Concrete Product)角色 简单工厂模式所创建的具体实例对象

    三、具体实例

    现在有两个类,分别是Apple和Banana,都有一个Get方法:

    Apple.java

    package cc.dewdrop;
    
    public class Apple{
    	public void get(){
    		System.out.println("采集苹果");
    	}
    }
    

     Banana.java

    package cc.dewdrop;
    
    public class Banana{
    	public void get(){
    		System.out.println("采集香蕉");
    	}
    }
    

     在主方法中实例化并分别调用个体方法:

    package cc.dewdrop;
    
    public class SimpleFactory {
    
    	public static void main(String[] args) {
    		Apple apple = new Apple();
    		Banana banana = new Banana();
    		apple.get();
    		banana.get();
        }
    }
    

     发现两个类都有一个共同的get方法,那么我们就可以抽象出一个接口,然后Apple和Banana两个类分别实现这个接口:

    Fruit.java

    package cc.dewdrop;
    
    public interface Fruit {
    	public void get();
    }
    

     Apple.java

    package cc.dewdrop;
    
    public class Apple implements Fruit{
    	public void get(){
    		System.out.println("采集苹果");
    	}
    }
    

     Banana.java

    package cc.dewdrop;
    
    public class Banana implements Fruit{
    	public void get(){
    		System.out.println("采集香蕉");
    	}
    }
    

     在主方法中就可以使用下面这种方式来创建对象:

    public class SimpleFactory {
    
    	public static void main(String[] args) {
    		 Fruit apple = new Apple();
    		 Fruit banana = new Banana();
    		 apple.get();
    		 banana.get();
        }
    }
    

     根据简单工厂模式的特点,现在就需要创建一个类来创建类的对象:

    FruitFactory.java

    package cc.dewdrop;
    
    public class FruitFactory {
    	 /**
    	 * 获得Apple实例
    	 */
    	 public Fruit getApple() {
    	 return new Apple();
    	 }
    	
    	 /**
    	 * 获得Banana实例
    	 */
    	 public Fruit getBanana() {
    	 return new Banana();
    	 }
    }
    

     在主方法中就可以使用如下方式进行调用:

    public class SimpleFactory {
    
    	public static void main(String[] args) {
    		Fruit apple = new FruitFactory().getApple();
    		Fruit banana = new FruitFactory().getBanana();
    		apple.get();
    		banana.get();
        }
    }
    

     再进一步,我们可以修改工厂类,使用静态方法来创建对象:

    FruitFactory.java

    package cc.dewdrop;
    
    public class FruitFactory {
    	 /**
    	 * 获得Apple实例
    	 */
    	 public static Fruit getApple() {
    	 return new Apple();
    	 }
    	
    	 /**
    	 * 获得Banana实例
    	 */
    	 public static Fruit getBanana() {
    	 return new Banana();
    	 }
    }
    

     在主方法中就可以直接使用类名来调用:

    public class SimpleFactory {
    
    	public static void main(String[] args) {
    		Fruit apple = FruitFactory.getApple();
    		Fruit banana = FruitFactory.getBanana();
    		apple.get();
    		banana.get();
        }
    }
    

     进一步改进工厂类,希望有一个公用的方法来创建所有产品的对象:

    FruitFactory.java

    package cc.dewdrop;
    
    public class FruitFactory {
    	public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException {
    		if (type.equalsIgnoreCase("apple")) {
    			return Apple.class.newInstance();
    		} else if (type.equalsIgnoreCase("banana")) {
    			return Banana.class.newInstance();
    		} else {
    			System.out.println("class not found");
    		}
    		return null;
    	}
    }
    

     在主方法中使用如下方式调用:

    public class SimpleFactory {
    
    	public static void main(String[] args) {
    		Fruit apple = FruitFactory.getFruit("apple");
    		Fruit banana = FruitFactory.getFruit("banana");
    		apple.get();
    		banana.get();
        }
    }
    

     这样调用工厂类创建对象的操作就简化了很多,但是还有一个缺点,就是如果在新增加一个类是,就必须修改工厂类。那么此时工厂类可以做出如下修改:

    FruitFactory.java

    package cc.dewdrop;
    
    public class FruitFactory {
    	public static Fruit getFruit(String type)
    			throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    		return (Fruit) Class.forName(type).newInstance();
    	}
    }
    

     需要注意一点的是,在调用的时候需要使用类的完整路径(包括包名):

    public class SimpleFactory {
    
    	public static void main(String[] args) {
    		Fruit apple = FruitFactory.getFruit("cc.dewdrop.Apple");
    		Fruit banana = FruitFactory.getFruit("cc.dewdrop.Banana");
    		apple.get();
    		banana.get();
        }
    }
    

     四、简单工厂模式的优缺点

          在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化
          不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

  • 相关阅读:
    读书笔记——吴军《态度》
    JZYZOJ1237 教授的测试 dfs
    NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论
    [JZYZOJ 1288][洛谷 1005] NOIP2007 矩阵取数 dp 高精度
    POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数
    POJ2157 Check the difficulty of problems 概率DP
    HDU3853 LOOPS 期望DP 简单
    Codeforces 148D. Bag of mice 概率dp
    POJ3071 Football 概率DP 简单
    HDU4405 Aeroplane chess 飞行棋 期望dp 简单
  • 原文地址:https://www.cnblogs.com/zhangtingkuo/p/4715283.html
Copyright © 2011-2022 走看看