zoukankan      html  css  js  c++  java
  • 设计模式之工厂模式 (二)

    工厂模式分为三大类

    1. 简单工厂(SimpleFactory)
    2. 工厂方法模式(Factory Method)
    3. 抽象工厂模式(Abstract Factory)
    4. 动态工厂(Dynamic Factory。属于优化版简单工厂)

    目的:

           工厂模式主要是为创建对象提供过渡接口。以便将创建对象的详细过程屏蔽隔离起来,达到提高灵活性的目的。



    一、简单工厂

    组成例如以下:

    (1) 工厂类角色:这是本模式的核心。含有一定的商业逻辑和推断逻辑。在java中它往往由一个详细类实现。

            (2) 抽象产品角色:它通常是详细产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。

            (3) 详细产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个详细类实现。



    详细样例:

    抽象产品、详细产品角色类定义例如以下:

    package com.open.design.factory;
    
    public class SimpleFactoryData {
    	
    	
    	//2.抽象产品角色:它通常是详细产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
    	public interface Car
    	{
    		void printName();
    	}
    	
    	
    	//3.详细产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个详细类实现。
    	public static class Benz implements Car
    	{
    		@Override
    		public void printName() {
    			System.out.println("i am Benz.");
    		}
    	}
    	
    	public static  class BMW implements Car
    	{
    		@Override
    		public void printName() {
    			System.out.println("i am BMW.");
    		}
    	}
    	
    	public static class Audi implements Car
    	{
    		@Override
    		public void printName() {
    			System.out.println("i am Audi.");
    		}
    	}
    	
    	public static class Tesla implements Car
    	{
    		@Override
    		public void printName() {
    			System.out.println("i am Tesla.");
    		}
    	}
    }
    
    
    
    
    
    
    
    
    


    工厂类定义例如以下:
    package com.open.design.factory;
    
    import com.open.design.factory.SimpleFactoryData.Car;
    
    //1.工厂类角色:这是本模式的核心,含有一定的商业逻辑和推断逻辑。在java中它往往由一个详细类实现
    public class SimpleFactory {
    
    	
    	public static Car produce(String carName)
    	{
    		Car car=null;
    		if("Benz".equals(carName))
    		{	
    			car=new SimpleFactoryData.Benz();
    		}
    		else if("BMW".equals(carName))
    		{
    			car=new SimpleFactoryData.BMW();
    		}
    		else if("Audi".equals(carName))
    		{
    			car=new SimpleFactoryData.Audi();
    		}
    		else if("Tesla".equals(carName))
    		{
    			car=new SimpleFactoryData.Tesla();
    		}
    		
    		return car;	
    	}
    }
    


    測试类例如以下:
    package com.open.design.factory;
    
    import com.open.design.factory.SimpleFactoryData.Car;
    
    public class SimpleFactoryTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Car car=SimpleFactory.produce("Benz");
    		car.printName();
    		
    		car=SimpleFactory.produce("BMW");
    		car.printName();
    		
    		car=SimpleFactory.produce("Audi");
    		car.printName();
    		
    		car=SimpleFactory.produce("Tesla");
    		car.printName();
    
    	}
    
    }
    

    打印结果例如以下:



    长处与缺点:

    简单工厂方法的长处是当在系统中引入新产品时不必改动client,但须要个改动工厂类。这个工厂类集中了全部产品创建逻辑。形成了一个无所不知的全能类(也称上帝类),假设此类出问题了,整个应用都受大影响。



    二、工厂方法模式(也称多态工厂)

    组成例如以下:

          (1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是详细工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
          (2)详细工厂角色:它含有和详细业务逻辑有关的代码。

    由应用程序调用以创建相应的详细产品的对象。

          (3)抽象产品角色:它是详细产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

          (4)详细产品角色:详细工厂角色所创建的对象就是此角色的实例。在java中由详细的类来实现。


    详细样例例如以下:

    抽象产品、详细产品角色类定义例如以下:

    package com.open.design.factory;
    
    public class PolymorphicData {
    	
    	
    	//3.抽象产品角色:它是详细产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

    public interface Car { void printName(); } //4.详细产品角色:详细工厂角色所创建的对象就是此角色的实例。在java中由详细的类来实现。 public static class Sedan implements Car { @Override public void printName() { System.out.println("i am Sedan."); } } public static class Train implements Car { @Override public void printName() { System.out.println("i am Train."); } } public static class Bike implements Car { @Override public void printName() { System.out.println("i am Bike."); } } }



    抽象工厂、详细工厂类定义例如以下:

    package com.open.design.factory;
    
    import com.open.design.factory.PolymorphicData.Car;
    
    public class PolymorphicFactory {
    
    	//1.抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是详细工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
    	public static abstract class CarFactory
    	{
    		abstract Car createCar();
    	}	
    
    	//2.详细工厂角色:它含有和详细业务逻辑有关的代码。

    由应用程序调用以创建相应的详细产品的对象。 public static class SedanFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Sedan(); }; } public static class TrainFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Train(); }; } public static class BikeFactory extends CarFactory { public Car createCar() { return new PolymorphicData.Bike(); }; } }


    測试类例如以下:

    package com.open.design.factory;
    
    import com.open.design.factory.PolymorphicData.Car;
    import com.open.design.factory.PolymorphicFactory.BikeFactory;
    import com.open.design.factory.PolymorphicFactory.CarFactory;
    import com.open.design.factory.PolymorphicFactory.SedanFactory;
    import com.open.design.factory.PolymorphicFactory.TrainFactory;
    
    public class PolymorphicTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		CarFactory factory=new SedanFactory();
    		Car car =factory.createCar();
    		car.printName();
    		
    		factory=new TrainFactory();
    		car =factory.createCar();
    		car.printName();
    		
    		factory=new BikeFactory();
    		car =factory.createCar();
    		car.printName();
    
    	}
    
    }
    

    打印结果:



    长处与缺点:

           当在系统中引入新产品时,既不必改动client。又不必改动详细工厂角色能够较好的对系统进行扩展。可是当产品种类繁多时。工厂类成倍数增长(由于种类越多,与之相应的工厂类也越多)

        在工厂方法模式中,核心的工厂类不再负责全部产品的创建,而是将详细创建的工作交给子类去做。这个核心工厂则变为抽象工厂角色,仅负责给出具工厂子类必须实现的接口,而不接触哪一产品创建的细节。

    这样的抽象的结果,使这样的工厂方法模式能够用来同意系统不改动详细工厂角色的情况下引进新产品,这一特点无疑使得工厂模式具有超过简单工厂模式的优越性。



    三、抽象工厂

    组成与工厂方法模式一致,仅仅只是抽象工厂是针对多个产品等级结构,工厂方法是针对一个产品等级结构。(产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。比方AMD的CPU和ADM芯片的主板,组成一个家族。Intel的CPU和Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产品等级:CPU,主板。


    详细样例例如以下:

    抽象产品、详细产品角色类定义例如以下:

    package com.open.design.factory;
    
    
    public class AbstractFactryCar {
    	
    	
    	//2.抽象产品角色:它通常是详细产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
    	public interface Car
    	{
    		void printName();
    	}
    	
    	
    	//3.详细产品角色:工厂类所创建的对象就是此角色的实例。

    在java中由一个详细类实现。 public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }


    package com.open.design.factory;
    
    
    public class AbstractFactryHouse {
    	
    	
    	//2.抽象产品角色:它通常是详细产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。

    public interface House { void printHouseName(); } //3.详细产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个详细类实现。 public static class Villa implements House { @Override public void printHouseName() { System.out.println("i am Villa."); } } public static class TileRoofedHouse implements House { @Override public void printHouseName() { System.out.println("i am TileRoofedHouse."); } } public static class CommodityHouse implements House { @Override public void printHouseName() { System.out.println("i am CommodityHouse."); } } }


    抽象工厂、详细工厂类定义例如以下:

    package com.open.design.factory;
    
    import com.open.design.factory.AbstractFactryCar.Car;
    import com.open.design.factory.AbstractFactryHouse.House;
    
    public class AbstractFactry {
    
    	//抽象工厂类
    	public static abstract class AbsDream
    	{
    		public abstract Car createCar();
    		public abstract House createHouse();
    	}
    
    	
    	//2.详细工厂角色:它含有和详细业务逻辑有关的代码。

    由应用程序调用以创建相应的详细产品的对象。

    public static class DreamAFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Benz(); }; public House createHouse() { return new AbstractFactryHouse.TileRoofedHouse(); }; } public static class DreamBFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Audi(); }; public House createHouse() { return new AbstractFactryHouse.CommodityHouse(); }; } public static class DreamCFactory extends AbsDream { public Car createCar() { return new AbstractFactryCar.Tesla(); }; public House createHouse() { return new AbstractFactryHouse.Villa(); }; } }


    測试类例如以下:

    package com.open.design.factory;
    
    import com.open.design.factory.AbstractFactry.AbsDream;
    import com.open.design.factory.AbstractFactryCar.Car;
    import com.open.design.factory.AbstractFactryHouse.House;
    
    public class AbstractFactryTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		AbsDream dream = new AbstractFactry.DreamAFactory();
    		Car car =dream.createCar();
    		House house=dream.createHouse();
    		
    		car.printName();
    		house.printHouseName();
    		
    		//-------------------
    		dream = new AbstractFactry.DreamBFactory();
    		car =dream.createCar();
    		house=dream.createHouse();
    		
    		car.printName();
    		house.printHouseName();
    		
    		//-------------------
    		dream = new AbstractFactry.DreamCFactory();
    		car =dream.createCar();
    		house=dream.createHouse();
    		
    		car.printName();
    		house.printHouseName();
    		
    
    	}
    
    }
    

    打印结果例如以下:



    长处与缺点:

    抽象工厂模式面对的问题是多产品等级结构的系统设计。抽象工厂模式的每一个工厂创造出来的都是一族产品,而不是一个或者一组。


    四、动态工厂

    组成与简单工厂类似。


    详细样例:

    抽象产品、详细产品角色类定义例如以下:

    package com.open.design.factory;
    
    public class DynamicFactoryData {
    	
    	
    	//2.抽象产品角色:它通常是详细产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
    	public interface Car
    	{
    		void printName();
    	}
    	
    	
    	//3.详细产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个详细类实现。

    public static class Benz implements Car { @Override public void printName() { System.out.println("i am Benz."); } } public static class BMW implements Car { @Override public void printName() { System.out.println("i am BMW."); } } public static class Audi implements Car { @Override public void printName() { System.out.println("i am Audi."); } } public static class Tesla implements Car { @Override public void printName() { System.out.println("i am Tesla."); } } }


    工厂类定义例如以下:

    package com.open.design.factory;
    
    import java.lang.reflect.Constructor;
    
    import com.open.design.factory.DynamicFactoryData.Car;
    
    
    
    public class DynamicFactory {
    
    	public static Car produce(String carName)
    	{
    		ClassLoader mClassLoader=DynamicFactory.class.getClassLoader();
    		try {
    			Class<?

    > mClass = mClassLoader.loadClass(carName); Constructor<?

    >[] mConstructor=mClass.getConstructors(); return (Car) mConstructor[0].newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } }


    測试类例如以下:

    package com.open.design.factory;
    
    import com.open.design.factory.DynamicFactoryData.Car;
    
    
    
    public class DynamicFactoryTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Car car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Benz");
    		car.printName();
    	
    		car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$BMW");
    		car.printName();
    		
    		car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Audi");
    		car.printName();
    		
    		car=DynamicFactory.produce("com.open.design.factory.DynamicFactoryData$Tesla");
    		car.printName();
    	}
    
    }
    

    打印结果例如以下:



    长处与缺点:

    简单模式的优化版,代码简洁。




    总结:

    (1)简单工厂模式是由一个详细的类去创建其它类的实例。

     (对于添加新的产品。无能为力) 
    (2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成详细的对象,这样做的目的是将类的实例化操作延迟到子类中完毕。

     (支持添加新产品) 
    (3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。而无须指定他们详细的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。

    (对于添加新的产品,无能为力。支持添加产品族)




    本文代码地址:https://github.com/zz7zz7zz/design-pattern

    參考博文:http://www.cnblogs.com/forlina/archive/2011/06/21/2086114.html

                        http://www.cnblogs.com/devinzhang/archive/2011/12/19/2293160.html

  • 相关阅读:
    ES10(2019)有哪些更新和新特性?
    搞不懂JS中赋值·浅拷贝·深拷贝的请看这里
    Vue Nginx反向代理配置 解决生产环境跨域
    react的事件处理为什么要bind this 改变this的指向?
    没有用到React,为什么我需要import引入React?
    git的基本使用和多人协作合并管理
    JSON对象和JavaScript对象直接量的区别--不同之处
    (Demo分享)利用原生JavaScript-ScrollLeft-实现做轮播广告通知
    (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
    软件测试行业的职业发展路线如何?如何快速突破职业瓶颈?
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7059354.html
Copyright © 2011-2022 走看看