工厂模式 订阅
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。 展开全文
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
信息
本    质
工厂方法代替new操作
类    别
管理模式
俗    称
实例化对象模式
中文名
工厂模式
实    例
Jive论坛
外文名
Factory Method
工厂模式编程开发
工厂模式定义我们以类Sample为例, 如果我们要创建Sample的实例对象:Sample sample=new Sample();可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值 查询数据库等。首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成:Sample sample=new Sample(参数);但是,如果创建sample实例时所做的初始化工作不是像赋值这样简单的事,可能是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重构)。为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有悖于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间耦合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个接口.Sample是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:ISample mysample=new MySample();ISample hissample=new HisSample();随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是无法避免的.但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
收起全文
精华内容
下载资源
问答
  • 3. Qt工厂模式工程 4. Qt工厂模式例程 5. Qt工厂模式例子 6. 简单工厂模式 部分源码实例: // 奔驰工厂 class BenzFactory : public AFactory { public: ICar* CreateCar() { return new BenzCar(); } }; // ...
  • Java中工厂模式案例

    2019-01-17 16:36:01
    1.简单工厂模式(simple factory)2.工厂方法模式(factory mathoud)3.抽象工厂模式(abstract factory)
  • 乐华板卡 进工程模式方法!!!
  • 工程模式(EngineerMode,简写为EngMode),工程师用来调试底层硬件的各项参数的工具,通过暗码的方式进入,完成对电话相关参数的设置、网络相关的设置、调试手段的设置、系统信息的读取等;它不依赖于上层,可以在...
  • java 创建型模式--工厂模式(Factory Pattern)示范代码demo,关于工厂模式可以查看我的博客 http://blog.csdn.net/u012930316/article/details/54599580
  • 工厂方法模式、简单工厂模式、抽象工程模式

    千次阅读 多人点赞 2018-04-07 22:11:06
    工厂设计模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。 针对的问题:在面向对象编程中,最...

    1.概述

    工厂设计模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

    1.1. 针对的问题

    在面向对象编程中,最常用的方法是new一个操作符产生一个对象实例,new对象操作符就是用来构造对象实例的,但是在一些情况下,new操作符直接生成对象会带来一些问题,举例说,许多类型对象的创建都需要一系列的步骤,可能需要计算或取得对象的初始设置,选择生成哪个子对象实例,或者在生成需要的对象之前必须先生成一些辅助功能的对象,这些情况下,对象的建立就是一个过程,不仅是一个操作。

    1.2. 分析

    这里写图片描述
    上图就是没有工厂模式时,用户需要自己new一辆车,这样,车和人就耦合在了一起。
    那么怎么能够方便的构建对象实例,而不关心构造对象实例的细节和复杂过程呢,那就是建立一个工厂来创建对象。把创建的过程封装到工厂里。

    1.3. 工厂模式类型

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

    1. 简单工厂模式
    2. 工厂方法模式
    3. 抽象工厂模式

    一般将简单工厂模式看为工厂方法模式的一种特例,二者归为一类。

    2. 三种工厂模式特征及实现

    2.1 简单工厂模式

    2.1.1. 角色组成

    这里写图片描述

    1. 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品

    2. 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。

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

    2.1.2. 实现
    //产品类
    abstract class BMW{
    	public BMW(){}
    }
    
    //具体产品类
    public class BMW100 extends BMW{
    	public BMW100(){
    	    System.out.println("this is BMW100");
    	}
    }
    public class BMW200 extends BMW{	
    	public BMW200(){
    		System.out.println("this is BMW200");
       }
    }
    
    //工厂类
    public class Factory{
    	public BMW CreateBMW(int type){
    		if(type ==100) return new BMW100();
    		if(type ==200) return new BMW200();
    		else return null;
        }
    }
    
    
    2.1.3. 分析

    在简单工厂中,当客户不再满足现有的车型号时,想要一种更快的车,只要这种车满足抽象产品指定的规则,只要通知工厂类增加相应的逻辑就好了,但是每增加一种车,都要在工厂类中增加相应的逻辑,工厂类十分被动,这样的工厂类成为全能类或者上帝类。

    2.2 工厂方法模式

    2.2.1. 角色构成

    1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

    2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

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

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

    工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的上帝类,分担了对象承受的压力。

    2.2.2. 实现
    //抽象产品类
    abstract class BMW()
    {
        public BMW();
    }
    
    // 具体产品类 四种车,宝马1系,(两种),2系(两种)
    public class BMW100 extends BMW
    {
    	public BMW100()
    	{
    		System.out.println("this is BMW100");
    	}
    }
    public class BMW109 extends BMW
    {
    	public BMW109()
    	{
    		System.out.println("this is BMW100");
    	}
    }
    public class BMW200 extends BMW
    {
    	public BMW200()
    	{
    		System.out.println("this is BMW200");
    	}
    }
    public class BMW209 extends BMW
    {
    	public BMW209()
    	{
    		System.out.println("this is BMW209");
    	}
    }
    
    
    //抽象工厂角色
    interface Factory
    {
        BMW createBMW();
    }
    
    //具体工厂角色
    public class FactoryBMW1 implements FactoryBMW{  
      
        @Override  
        public BMW100 createBMW() {  
            return new BMW100();  
        }  
      
    }  
    public class FactoryBMW2 implements FactoryBMW {  
        @Override  
        public BMW200 createBMW() {  
      
            return new BMW200();  
        }  
    }   //分为100的工厂和200的工厂(省略了两个工厂)。都实现了工厂的接口
    
    
    2.2.3. 分析

    想加一辆车,就单独加车的类,这个车的工厂,然后只修改客户端的代码即可。工厂方法模式实现时,客户端需要决定实例化哪一个工厂来创建对象,工厂方法把简单工厂的内部逻辑移到了客户端代码来执行。

    2.3. 抽象工厂模式

    抽象工厂模式是工厂方法模式的升级版本,它用来创建一组相关或者相互依赖的对象。

    抽象工厂模式提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类。就是一个工厂里放一些相关的类,使工厂数减少

    最大的好处便是易于交换产品系列,其次是让具体的创建实例过程与客户端分离,客户端通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离。不会出现在客户代码中

    2.3.1. 角色

    这里写图片描述

    2.3.2. 实现

    抽象工厂方法就是一个工厂里生产不同等级结构中的一个(其中一种车)中的不同的配件(不同的车的属性)

    //抽象产品类1 发动机以及型号    
    public interface Engine {    
      
    }    
    //抽象产品类2 空调以及型号    
    public interface Aircondition {    
      
    }
    
    //具体产品类
    public class EngineA extends Engine{    
        public EngineA(){    
            System.out.println("制造-->EngineA");    
        }    
    }    
    public class EngineB extends Engine{    
        public EngineB(){    
            System.out.println("制造-->EngineB");    
        }    
    }  
        
    public class AirconditionA extends Aircondition{    
        public AirconditionA(){    
            System.out.println("制造-->AirconditionA");    
        }    
    }    
    public class AirconditionB extends Aircondition{    
        public AirconditionB(){    
            System.out.println("制造-->AirconditionB");    
        }    
    }
    
    //抽象工厂    
    public interface AbstractFactory {    
        //制造发动机  
        public Engine createEngine();  
        //制造空调   
        public Aircondition createAircondition();   
    }    
    
    
    //具体工厂类  
    public class 奔驰工厂 implements AbstractFactory{    
            
        @Override    
        public Engine createEngine() {      
            return new EngineA();    
        }    
        @Override    
        public Aircondition createAircondition() {    
            return new AirconditionA();    
        }    
    }    
    //为宝马车生产配件
    public class 宝马工厂 implements AbstractFactory {    
        
         @Override    
        public Engine createEngine() {      
            return new EngineB();    
        }    
        @Override    
        public Aircondition createAircondition() {    
            return new AirconditionB();    
        }    
    }
    
    2.3.3. 分析

    抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。

    展开全文
  • 在《设计模式》一书中工厂模式提到了: 工厂方法模式(Factory Method) 抽象工厂模式 (Abstract Factory) 但是在实际过程中还有一种工厂模式经常被使用,那就是 简单工厂模式(Simple Factory)。有一种常见的...
  • 工厂模式在一些设计模式的书中分为简单工厂模式工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。
  • 单例模式工厂模式结合应用,实现了产品的生产,适合用做课程设计,包含详细文档和代码。Java语言。喜欢的可以下载来看看那
  • 3种工厂模式

    千次阅读 2019-05-03 20:49:40
    3种工厂模式 问题描述 简单工厂模式:模拟女娲造人,如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,实现该场景。...抽象工程模式:电脑配件生产内存、CPU等硬件设备,这些...

    3种工厂模式

    1. 问题描述
      简单工厂模式:模拟女娲造人,如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,实现该场景。现需要增加一个新的Robot类,如果传入参数R,则返回一个Robot对象,对代码进行修改并注意女娲的变化。
      工厂方法模式:海尔工厂生成海尔空调,美的工厂生产美的空调,描述该场景,绘制类图并编程实现
      抽象工程模式:电脑配件生产内存、CPU等硬件设备,这些内存、CPU的品牌、型号并不一定相同,根据“产品等级结构-产品族”示意图,实现电脑配件生产过程并绘制相应的类图,绘制类图并编程实现

    2. 解题思路
      简单工厂模式,根据不同参数返回不同对象,可用接口实现。Man Woman Robot3个类实现一个Person类接口,重写接口中的方法。女娲类作为工厂,应当完成返回不同对象的任务。即定义一个带参方法,判断参数并返回相应对象。最后需要一个类,作为操作入口,调用女娲类中方法,传入实参,返回对象,根据向上转型用抽象的person来实现3个类得到结果。
      工厂方法模式:与上一个模式不同的是,该模式是一个抽象工厂下可以继承多个不同工厂,各工厂实现不同产品的生产。因此定义一个接口AirconditionFactory为抽象工厂,海尔工厂和美的工厂各自实现接口,重写生产空调的方法。再定义一个接口Aircondition,海尔空调和美的空调实现该接口方法。此外,定义与两个接口关联的类,和上面方法相同,通过返回具体工厂对象,调用相应工厂方法来实现题目要求
      抽象工厂方法,不改变产品等级的情况下对原有等级进行组装。几个工厂产品生产种类相同,数量相同。实现一个工厂和相应产品的对应即是一个产品族。

    3. 算法构造
      在这里插入图片描述
      简单工厂模式

    在这里插入图片描述
    工厂方法模式

    在这里插入图片描述
    抽象工程模式

    4.实现代码

    简单工厂模式:
    package SimpleFactory;
    
    // Person接口
    public interface Person {
    	public void makePeople();
    }
    
    // Man 类
    public class Man implements Person {
    	public void makePeople() {
    		System.out.println("女娲制造一个男人");
    	}
    }
    
    // Woman 类
    public class Woman implements Person {
    	public void makePeople() {
    		System.out.println("女娲制造一个女人");
    	}
    }
    
    // Robot类
    public class Robot implements Person {
    	public void makePeople() {
    		System.out.println("女娲制造一个机器人");
    	}
    }
    
    //Nvwa 类
    public class Nvwa {
    	public static Person make(String args) {
    		if(args.equalsIgnoreCase("M")) {
    			return new Man(); 
    		}else if(args.equalsIgnoreCase("W")) {
    			 return new Woman();
    		}else if(args.equalsIgnoreCase("R")) {
    			return new Robot();
    		}else {
    			return null;
    			}
    		}
    	}
    	
    // NvwamakePeople类
    public class NvwamakePeople {
    	public static void main(String[] args) {
    		Person person ;  //创建一个对象
    		person=Nvwa.make("M");
    		person.makePeople();
    		  person=Nvwa.make("W");
    		person.makePeople();
    		 person=Nvwa.make("R");
    		person.makePeople();
    	}
    }
    
    
    工厂方法模式:
    package FactoryMethod;
    
    // AirconditionFactory接口
    public interface AirconditionFactory {
    	public static Aircondition produceAircondition(String args) {
      		  return null;
    	 }
     }
     
    //HaierconditonFactory 类
    public class HaierconditonFactory  implements AirconditionFactory {
    	public  static Aircondition produceAircondition(String args) {
    		if(args.equalsIgnoreCase("Haier")) {
    			System.out.println("海尔工厂生产海尔空调")
    			 return new HaierAircondition();
     		}else {
     			System.out.println("海尔工厂不生产非海尔品牌空调");
     			return null;
     			}
     		}
     	}
     	
    //MideaAirconditionFactory类
    public class MideaAirconditionFactory implements AirconditionFactory {
    	public static Aircondition produceAircondition(String args) {
    		if(args.equalsIgnoreCase("Midea")) {
     			System.out.println("美的工厂生产美的空调");
    			return new MideaAircondition();
    		}else {
    			System.out.println("美的工厂不生产非美的品牌空调");
    			return null;
    		}
    	}
    }
    
    //Aircondition接口
    public interface Aircondition {
    	public static void play() {
    	}
    }
    
    //HaierAircondition 类
    public class HaierAircondition implements Aircondition {
    	public static void play() {
    		System.out.println("海尔空调正在运行中.....");
    	}
    }
    
    //MideaAircondition类
    public class MideaAircondition implements Aircondition{
    	public static void play() {
    		System.out.println("美的空调正在运行中.....");
    	}
    }
    
    //client类
    public class client {
    	public static void main(String[] args) {	
    		Aircondition aircondition; //创建一个对象
    		aircondition = HaierconditonFactory.produceAircondition("Haier");
    		HaierAircondition.play();
    		aircondition = MideaAirconditionFactory.produceAircondition("Midea");
    		MideaAircondition.play();
    	}
    }
    
    抽象工程模式:
    package abstractProject;
    
    // Factory 接口
    public interface Factory {
    	public static RAM produceRAM(String args) {
    		return null;
    	}
    	public static CPU produceCPU(String args) {
    		return null;
    	}
    }
    
    // MacFactor类
    public class MacFactory implements Factory {
    	public static RAM produceRAM(String args) {
    		if(args.equalsIgnoreCase("Mac")) {
    			System.out.println("Mac工厂生产MacRAM ");
    			return new MacRAM();
    		}else {
    			System.out.println("Mac工厂不生产非Mac牌RAM ");
    			return null;
    		}
    	}	
    	public static CPU produceCPU(String args) {
    		if(args.equalsIgnoreCase("Mac")) {
    			System.out.println("Mac工厂生产MaCPU ");
       			return new MacCPU();
       		}else {
    			System.out.println("Mac工厂不生产非MacC牌CPU ");
    			return null;
    			}
    		}
    	}
    	
    //PCFactory 类
    public class PCFactory implements Factory {
    	public static RAM produceRAM(String args) {
     		 if(args.equalsIgnoreCase(PC")) {
       			System.out.println("PC工厂生产PCRAM ");
       			return new PCRAM();
       		}else {
       			System.out.println("PC工厂不生产非PC牌RAM ");
       			return null;
       			}
       		}
       	public static CPU produceCPU(String args) {
       		if(args.equalsIgnoreCase("PC")) {
       			System.out.println("PC工厂生产PCCPU ");
       			return new PCCPU();
       		}else {
       			System.out.println("PC工厂不生产非PC牌CPU ");
       			return null;
       			}
       		}
       	}
    
    // CPU接口
    public interface CPU {
     	public static void play() {}
     }
     
    // MacCPU类
    public class MacCPU implements CPU {
    	public static void play() {
    		System.out.println("MacCPU正在运行中....");
    	}
    }
    
    // PCCPU 类
    public class PCCPU implements CPU {
    	public static void play() {
    		System.out.println("PCCPU正在运行中....");
    	}
    }
    
    // RAM 接口
    public interface RAM {
    	public static void save() {}
    }
    
    // MacRAM 类
    public class MacRAM implements RAM {
    	public static void save() {
    		System.out.println("MacRAM正在存储中....");
    	}
    }
    
    // PCRAM 类
    public class PCRAM implements RAM {
    	public static void save() {
    		System.out.println("PCRAM正在存储中....");
    	}
    }
    
    //client 类
    public class client {
    	public static void main(String[] args) {
    		CPU cpu;
    		RAM ram;
    		ram = PCFactory.produceRAM("PC");
    		PCRAM.save();
    		cpu = PCFactory.produceCPU("PC");
    		PCCPU.play();
    		ram = MacFactory.produceRAM("Mac");
    		MacRAM.save();
    		cpu = PCFactory.produceCPU("PC");
    		MacCPU.play();
    	}
    }
    
    1. 调试
      简单工厂模式:
      在这里插入图片描述
      调用Nvwa的make方法
      在这里插入图片描述

    返回了man对象后继续调用man对象的makePeople方法
    在这里插入图片描述
    界面跳转到man对象中
    在这里插入图片描述
    控制台输出makePeple方法的语句

    工厂方法模式:
    在这里插入图片描述
    调用海尔工厂生产海尔空调的方法
    在这里插入图片描述
    界面跳转到海尔工厂,经过判断,输出语句并返回海尔空调对象
    在这里插入图片描述
    在变量界面可以看到返回的HaierAircondition对象
    在这里插入图片描述
    调用海尔对象方法输出语句,显示最终结果

    1. 测试及结果
      在这里插入图片描述
      简单工厂模式
      在这里插入图片描述
      工厂方法模式
      在这里插入图片描述
      抽象工厂模式

    2. 经验归纳
      这次对三种模式的编程实现很大程度上依靠了老师的课件。在简单工厂模式编码实现后其他两种模式在其基础上增加类和接口等,思想上也有不同。简单工厂模式重在返回的是对象,通过向上转型,虽然调用的是抽象类(即接口)的方法,实际上是返回的具体对象,因此返回的也是相应的方法中所写语句。工厂方法不同的在于不是一个工厂生产所有需要的产品,各种工厂继承抽象工厂的方法,生产相应的产品。因此,需要两个具体的类实现一个接口AirconditionFactory,另两个类实现一个接口Airconditio。此过程中我总是会不知道哪个方法写在哪个类里。这个应该通过绘制类图来确定,只要确定在最终的client类中调用的方法,弄清思路还是可以解决的。最后一个是抽象工厂模式,总体思路与上一个一样,只是每个工厂生产的产品不再是1个,各工厂生产的产品种类相同。这几种模式还需要几次练习,才可以熟练掌握。

    展开全文
  • 这是设计模式中简单工厂设计模式的源代码,工程中以一个计算器的示例来体现简单工厂模式的精髓。简单工厂模式主要解决创建对象的问题。
  • JAVA设计模式(01):创建型-工厂模式【简单工厂模式】(Simple Factory)
  • EC1308进入工程模式

    2014-09-11 19:50:54
    进入“工厂模式”以及退出办法,设置 、密码
  • 用C#抽象工厂编写的完整项目案例,项目虽小,但绝对正确无误,正常运行。内含数据库文件。适合帮助初学者了解抽象工厂项目的编程思想和项目架构
  • NULL 博文链接:https://xieyan30.iteye.com/blog/1695483
  • 手机工程模式代码大全 手机工程模式代码大全 1 联想 联想 K920 指令代码大全 可实现各种功能 以下指令都是进入手机的拔号器输入对应的代 码完全成的 #537999# 或 #537999* 打 开所有开发者选项 #0000# 查询手机系统...
  • 介绍的是工厂模式 包括简单工厂模式工厂方法模式、抽象工厂模式 包括PPT和代码
  • 简单工厂模式uml类图

    2018-03-07 10:09:52
    java设计模式 简单工厂模式uml类图,一张图就让你秒懂简单工厂模式
  • 深入浅出设计模式之抽象工厂模式+工厂方法模式+策略模式实现手机加工厂
  • 工厂模式: 每一种设计模式都有它要解决的问题: 工厂模式最主要解决的问题就是创建者和调用者的耦合,那么代码层面其实就是取消对new的使用。 工厂模式有三种: 1. 简单工厂模式 2. 工厂方法模式 3. 抽象方法模式 ...
  • 抽象工厂模式uml类图

    2018-03-07 10:41:31
    java设计模式 抽象工厂模式详解 一张图让你彻底明白抽象工厂模式
  • 深入浅出设计模式之抽象工厂模式+工厂方法模式+策略模式实现手机加工厂(加类图)
  • 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在抽象工厂模式中,接口是负责...
  • 设计模式(简单工厂模式_排序)手写的代码,自己写博客用
  • 一共四个包,从名字可以看出来,pre1是最差的写法,pre2是继承的写法,然后是简单工厂模式的写法和工厂模式的写法。
  • 1、抽象工厂模式+反射技术 2、抽象工厂模式+简单工厂模式 3、仅仅是抽象工厂模式
  • 简单工厂模式

    千次阅读 2020-12-14 21:51:16
    在日常开发中,凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替。 复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使用,则两者的耦合...

    在日常开发中,凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替。

    复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使用,则两者的耦合过重,后续业务更改,就需要在任何引用该类的源代码内进行更改,光是查找所有依赖就很消耗时间了,更别说要一个一个修改了。

    工厂模式的定义:

    是指定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。

    按实际业务场景划分,工厂模式有 3 种不同的实现方式,分别是

    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

    一、简单工厂模式

    1、简单工厂模式的定义

    简单工厂模式(Simple Factory Pattern) ,又叫作静态工厂方法模式(Static Factory Method Pattern)。

    我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。

    简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。
    简单工厂模式不在 GoF 23 种设计模式之列。

    2、简单工厂模式的结构

    (1)简单工厂模式主要 3个角色

    • 简单工厂(SimpleFactory):
      是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的-建产品类的方法可以被外界直接调用,创建所需的产品对象。
    • 抽象产品(Product):
      是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
    • 具体产品(ConcreteProduct):
      -是简单工厂模式的创建目标。

    (2)结构图如下:(图来自网络)
    在这里插入图片描述

    3、优缺点

    主要优点:

    • 结构简单,调用方便。工厂和产品的职责区分明确。
    • 客户端无需知道所创建具体产品的类名,只需知道参数即可。

    主要缺点:

    • 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。

    4、使用场景

    对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

    5、在框架源码中使用也很广泛

    • JDK源码中的 Calendar.getInstance()方法
    • Logback源码中多个重载的 getLogger()方法

    二、模式的通用实现

    代码如下:

    public class SimpleFactoryPattern {
        public static void main(String[] args) {
            Product product = SimpleFactory.makeProduct(2);
            product.show();
        }
        //抽象产品
        public interface Product {
            void show();
        }
        //具体产品:ProductA
        static class ConcreteProduct1 implements Product {
            @Override
            public void show() {
                System.out.println("具体产品1显示...");
            }
        }
        //具体产品:ProductB
        static class ConcreteProduct2 implements Product {
            @Override
            public void show() {
                System.out.println("具体产品2显示...");
            }
        }
        //具体产品:ProductC
        static class ConcreteProduct3 implements Product {
            @Override
            public void show() {
                System.out.println("具体产品3显示...");
            }
        }
        final class Const {
            static final int PRODUCT_A = 0;
            static final int PRODUCT_B = 1;
            static final int PRODUCT_C = 2;
        }
        static class SimpleFactory {
            public static Product makeProduct(int kind) {
                switch (kind) {
                    case Const.PRODUCT_A:
                        return new ConcreteProduct1();
                    case Const.PRODUCT_B:
                        return new ConcreteProduct2();
                    case Const.PRODUCT_C:
                        return new ConcreteProduct3();
                }
                return null;
            }
        }
    }
    

    三、模式的应用实例

    简易计算器为例,需求:输入两个数和运算符,得到结果。

    1、抽象产品

    public abstract class Operation {
        protected abstract double compute (double number1, double number2) throws Exception;
    }
    

    2、具体产品

    • 加法
    public class OperationAdd extends Operation{
        @Override
        protected double compute(double number1, double number2) {
            return number1 + number2;
        }
    }
    
    • 减法
    public class OperationSub extends Operation{
        @Override
        protected double compute(double number1, double number2) {
            return number1 - number2;
        }
    }
    
    • 乘法
    public class OperationMul extends Operation{
        @Override
        protected double compute(double number1, double number2) {
            return number1 * number2;
        }
    }
    
    • 除法
    public class OperationDiv extends Operation{
        @Override
        protected double compute(double number1, double number2) throws Exception {
            if(number2 == 0){
                throw new Exception("除数不能为0!");
            }
            return number1 / number2;
        }
    }
    

    3、简单工厂

    这里对简单工厂创建产品进行了优化。可以通过缓存、配置文件、反射和泛型等技术了优化。
    如果运算业务需要扩展,需要创建具体运算类即可,不需要再修改简单工厂类了。

    public class OperationFactory {
    
        private static final Map<String, Operation> cachedParsers = new HashMap<>();
    
        static {
            cachedParsers.put("+", new OperationAdd());
            cachedParsers.put("-", new OperationSub());
            cachedParsers.put("*", new OperationMul());
            cachedParsers.put("/", new OperationDiv());
        }
    
        public static Operation createOperate0(String operate) {
            if (operate == null || operate.isEmpty()) {
                return null;//返回null还是IllegalArgumentException全凭你自己说了算
            }
            return cachedParsers.get(operate);
        }
    
        /**
         *  createOperate0运用缓存技术,节省内存和对象创建的时间
         *  createOperate0 和 createOperate1 同理
         */
        public static Operation createOperate1(String operate){
            Operation operation = null;
            switch (operate){
                case "+":
                    operation = new OperationAdd(); break;
                case "-":
                    operation = new OperationSub(); break;
                case "*":
                    operation = new OperationMul(); break;
                case "/":
                    operation = new OperationDiv(); break;
            }
            return operation;
        }
    
         /**
          * createOperate1方法不符合开闭原则
          *      如果运算业务继续扩展,需要创建具体运算类,也需要修改简单工厂的 createOperate1方法。
          * 采用反射技术进行优化,即createOperate2方法
         */
        public static Operation createOperate2(String className){
            Operation operation = null;
            try {
                if(!(null == className || "".equals(className))){
                    operation = (Operation) Class.forName(className).newInstance();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return operation;
        }
    
        /**
         * createOperate2方法中类型强制转型,参数为字符串,可控性不高
         * 采用反射和泛型技术进行优化,即createOperate3方法
         */
        public static Operation createOperate3(Class<? extends Operation> clazz){
            try {
                if(null != clazz){
                    return clazz.newInstance();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

    4、测试

    public class Test {
        public static void main(String[] args) throws Exception {
            double num1 = 10;
            double num2 = 2;
            System.out.println(OperationFactory.createOperate0("*").compute(num1, num2));
            System.out.println(OperationFactory.createOperate1("*").compute(num1, num2));
    
            Operation operate2 = OperationFactory.createOperate2("cn.jq.learn.simplefactorypattern.OperationDiv");
            System.out.println(operate2.compute(num1, num2));
    
            Operation operate3 = OperationFactory.createOperate3(OperationAdd.class);
            System.out.println(operate3.compute(num1, num2));
        }
    }
    

    在这里插入图片描述

    参考文章:

    —— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。

    展开全文
  • 请用Java面向对象语言,利用简单工厂模式,实现简易计算器程序(加减乘除功能)。 在注释中回答以下问题: 1、 软件设计目标分别是什么? 2、 在相应的代码处解释设计目标实现的方式。
  • 程序员必知的23种设计模式工厂模式

    千次阅读 多人点赞 2020-04-29 17:02:20
    文章目录工厂模式1. 简单工厂模式2. 工厂方法模式3. 抽象工厂模式4. 工厂模式在Calendar 类中的应用5. 工厂模式小结 工厂模式 关于工厂模式的例子,有一个经典的披萨例子: 需要为披萨店建立一个项目: 披萨的项目:...

    工厂模式

    关于工厂模式的例子,有一个经典的披萨例子:

    需要为披萨店建立一个项目:

    披萨的项目:

    要便于披萨种类的扩展,要便于维护

    1. 披萨的种类很多(比如 GreekPizz、CheesePizz 等)

    2. 披萨的制作有 prepare,bake, cut, box

    3. 每个披萨除了prepare有些不同,其他的bake, cut, box操作都是一样的

    4. 用户可以订购披萨,用户输入披萨的名称,即开始对应披萨的制作工序。

    初步思路

    可以看出,披萨的制作过程都包含了prepare、bake、cut和box,既然每个披萨都需要这些工序,那么我们就可以将这些操作复用起来,怎么实现复用?最简单的方法就是设置一个Pizza的抽象类,实现了bake、cut和box的方法,然后让每个实际的Pizza类去继承这个抽象的Pizza类,而prepare方法就交由实际的Pizza类实现。

    如上述,当前一共有两个具体Pizza类,一个是GreekPizza类、一个是CheesePizza类,那么初次的类图就是这样的:
    在这里插入图片描述
    为了便于输出,我们增加一个属性name,用以区别每个具体的Pizza,还有和一个setName方法,用来设置name属性。

    Pizza类(用一个简单的输出表示运行了准备工序)

    public abstract class Pizza {
    	protected String name;
    
    	public abstract void prepare();
    
    	public void bake() {
    		System.out.println(name + " baking;");
    	}
    
    	public void cut() {
    		System.out.println(name + " cutting;");
    	}
    
    	public void box() {
    		System.out.println(name + " boxing;");
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    }
    

    各个实际Pizza类:

    public class CheesePizza extends Pizza {
    	public void prepare() {
    		setName("CheesePizza");
    		System.out.println(name + " preparing;");
    	}
    }
    
    public class GreekPizza extends Pizza {
    	public void prepare() {
    		setName("GreekPizza");
    		System.out.println(name + " preparing;");
    	}
    }
    

    当然,这只是描述了Pizza类之间的关系,我们还需要用来订购的披萨的类,类名为OrderPizza,OrderPizza类用来接收用户输入的字符串,根据用户输入的字符串,构造对应的Pizza具体类,然后输出对应的Pizza具体类:

    OrderPizza类:

    public class OrderPizza {
        
        
    	public OrderPizza() {
    		Pizza pizza = null;
    		do {
    			String ordertype = gettype();
    			if (ordertype.equals("greek")) {
    				pizza = new GreekPizza();
    			} else if (ordertype.equals("cheese")) {
    				pizza = new CheesePizza();
    			}
    			if (pizza == null)
    				break;
    			pizza.prepare();
    			pizza.bake();
    			pizza.cut();
    			pizza.box();
    		} while (true);
    
    	}
    
    	private String gettype() {
    		System.out.println("input pizza type:");
    		Scanner scanner = new Scanner(System.in);
    		return scanner.nextLine();
    	}
    }
    

    还需要构造一个客户端类PizzaStore,调用OrderPizza类。

    PizzaStore客户端类:

    public class PizzaStore {
    	public static void main(String[] args) {
    		new OrderPizza();
    	}
    }
    

    传统的方式的优缺点

    1. 优点是比较好理解,简单易操作。

    2. 缺点是违反了设计模式的ocp原则,即对扩展开放,对修改关闭。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.

    3. 比如我们这时要新增加一个Pizza的种类(Pepper披萨),我们需要做如下修改.

    4. 改进的思路分析

    分析: 修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味着,也需要修改,而创建Pizza的代码,往往有多处

    思路: 把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该类就可,其它有创建Pizza对象的代码就不需要修改了.-> 简单工厂模式

    1. 简单工厂模式

    基本介绍

    1. 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式

    2. 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)

    3. 在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式

    使用简单工厂模式

    简单工厂模式的设计方案: 定义一个可以实例化Pizaa对象的类,封装创建对象的代码。

    添加新Pizza类:

    public class PepperPizza extends Pizza {
    	public void prepare() {
    		setName("PepperPizza");
    		System.out.println(name + " preparing;");
    	}
    }
    

    添加简单工厂类:

    public class SimpleFactory {
    
    	public Pizza createPizza(String type) {
    		
    		Pizza pizza = null;
    		if (type.equals("greek")) {
    			return new GreekPizza();
    		} else if (type.equals("cheese")) {
    			return new CheessPizza();
    		} else if (type.equals("pepper")) {
    			return new PepperPizza();
    		}
    		return pizza;
    	}
    }
    

    修改OrderPizza类:

    public class OrderPizza {
    
    	private SimpleFactory simplefactory;
    	Pizza pizza = null;
    
    	public OrderPizza(SimpleFactory simpleFactory) {
    		setFactory(simpleFactory);
    		do {
    			String orderType = getType();
    			pizza = simplefactory.createPizza(orderType);
    			if (pizza == null)
    				break;
    			pizza.prepare();
    			pizza.bake();
    			pizza.cut();
    			pizza.box();
    		} while (true);
    	}
    
    	public void setFactory(SimpleFactory simplefactory) {
    		this.simplefactory = simplefactory;
    
    	}
    
    	private String getType() {
    		System.out.println("input pizza 种类:");
    		Scanner scanner = new Scanner(System.in);
    		return scanner.nextLine();
    	}
    
    }
    

    此时类之间的UML关系:
    在这里插入图片描述

    这样修改代码后,添加一个新披萨就会比修改前添加一个新披萨容易很多,也很容易定位到需要修改的位置。

    新的需求

    披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪pizza、

    北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza。

    如果使用简单工厂模式,在工厂中添加上述披萨类,会导致工厂类的创建过程很复杂,不易维护,如果可扩展性并不是特别好

    解决方案

    可以使用工厂方法模式或者是抽象工厂模式

    2. 工厂方法模式

    工厂方法模式介绍

    工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现(就是将工厂进行抽象)

    工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类

    添加的新披萨类:

    public class BJCheesePizza extends Pizza {
    
    	public void prepare() {
    		setName("BJCheesePizza");
    		System.out.println("prepare for BJCheesePizza");
    
    	}
    }
    
    public class BJPepperPizza extends Pizza {
    
    	public void prepare() {
    		setName("BJPepperPizza");
    		System.out.println("prepare for BJPepperPizza");
    
    	}
    
    }
    
    public class LDCheesePizza extends Pizza {
    
    	public void prepare() {
    		setName("LDCheesePizza");
    		System.out.println("prepare for LDCheesePizza");
    	}
    }
    
    public class LDPepperPizza extends Pizza {
    
    	public void prepare() {
    		setName("LDPepperPizza");
    		System.out.println("prepare for LDPepperPizza");
    	}
    }
    

    新添加的工厂类:

    public class BJPizzaFactory extends OrderPizza {
    
    	public Pizza createPizza(String type) {
    		Pizza pizza = null;
    		if (type.equals("cheese")) {
    			pizza = new BJCheesePizza();
    		} else if (type.equals("pepper")) {
    			pizza = new BJPepperPizza();
    		}
    		return pizza;
    	}
    
    }
    
    public class LDPizzaFactory extends OrderPizza {
    
    	public Pizza createPizza(String type) {
    		Pizza pizza = null;
    		if (type.equals("cheese")) {
    			pizza = new LDCheesePizza();
    		} else if (type.equals("pepper")) {
    			pizza = new LDPepperPizza();
    		}
    		return pizza;
    	}
    
    }
    

    修改OrderPizza类:

    public abstract class OrderPizza {
    
    	public abstract Pizza createPizza(String type);
    
    	public OrderPizza() {
    		Pizza pizza = null;
    		do {
    			String orderType = getType();
    			// 抽象方法,由工厂子类完成
    			pizza = createPizza(orderType);
    			if (pizza == null)
    				break;
    			pizza.prepare();
    			pizza.bake();
    			pizza.cut();
    			pizza.box();
    
    		} while (true);
    	}
    
    	private String getType() {
    		System.out.println("input pizza 种类:");
    		Scanner scanner = new Scanner(System.in);
    		return scanner.nextLine();
    	}
    
    }
    

    类之间的UML关系:
    在这里插入图片描述

    3. 抽象工厂模式

    基本介绍

    1. 抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类

    2. 抽象工厂模式可以将简单工厂模式工厂方法模式进行整合。

    3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。

    4. 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。

    抽象工厂模式比工厂方法模式更加抽象

    不再使用抽象类,使用一个工厂接口:

    public interface AbsFactory {
    	Pizza createPizza(String type);
    }
    

    修改OrderPizza类:

    public class OrderPizza {
    	private AbsFactory factory;
    	private Pizza pizza;
    
    	public OrderPizza(AbsFactory factory) {
    		this.factory = factory;
    		do {
    			pizza = factory.createPizza(getType());
    			if (pizza == null)
    				break;
    			pizza.prepare();
    			pizza.bake();
    			pizza.cut();
    			pizza.box();
    
    		} while (true);
    	}
    
    	private String getType() {
    		System.out.println("input pizza 种类:");
    		Scanner scanner = new Scanner(System.in);
    		return scanner.nextLine();	
    	}
    
    }
    

    类之间的UML关系:

    4. 工厂模式在Calendar 类中的应用

    以下为jdk1.8源代码

     public abstract class Calendar ... {
        ...
        // 需要获取实例
    	public static Calendar getInstance(){
            return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
        }
         
    	...
    		// 工厂
            if (aLocale.hasExtensions()) {
                String caltype = aLocale.getUnicodeLocaleType("ca");
                if (caltype != null) {
                    //根据不同的caltype返回不同类型的实例
                    switch (caltype) {
                    case "buddhist":
                    cal = new BuddhistCalendar(zone, aLocale);
                        break;
                    case "japanese":
                        cal = new JapaneseImperialCalendar(zone, aLocale);
                        break;
                    case "gregory":
                        cal = new GregorianCalendar(zone, aLocale);
                        break;
                    }
                }
            }
            ...
    }
    

    5. 工厂模式小结

    工厂模式的意义

    1. 将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。

    2. 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)

    3. 设计模式的依赖抽象原则

    • 创建对象实例时,不要直接 new 类, 而是把这个new 类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。

    • 不要让类继承具体类,而是继承抽象类或者是实现interface(接口)

    • 不要覆盖基类中已经实现的方法。

    展开全文
  • 文章:http://blog.csdn.net/hailushijie/article/details/8684435

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,003,695
精华内容 401,478
关键字:

工厂模式