zoukankan      html  css  js  c++  java
  • !!转!!java 简单工厂模式

    举两个例子以快速明白Java中的简单工厂模式:

    女娲抟土造人
    话说:“天地开辟,未有人民,女娲抟土为人。”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面。
    女娲造人,这就是简单工厂模式的应用。 

      首先,在这个造人的思想里面,有几个重要的角色:女娲本身、抽象的人的概念和女娲所造出的一个个具体的人。
      1.)女娲是一个工厂类,也就是简单工厂模式的核心角色。

            2.)具休的一个个的人,包括张三,李四等。这些人便是简单工厂模式里面的具体产品角色
      3.)抽象的人是最早只存在于女娲的头脑里的一个想法,女娲按照这个想法造出的一个个具体的人,便都符合这个抽象的人的定义。换言之,这个抽象的想法规定了所有具体的人必须都有的接口(特征或者功能)
       其UML类图出下所示:
        
    理解了上面的这些东西,再来理解下面的例子,对照理解,相信看完这篇文章,便对java简单工厂模式有一个很好的理解:


    有一个农场公司,专门向市场销售各类水果,在这个系统里需要描述下列水果:
         葡萄 Grape
         草莓 Stuawberry
         苹果 Apple
    水果与其他植物不同,最终可以采摘食用,那么一个自然的做法是建立一个各种水果都适用的接口,以便与其他农场里的植物区分开来,

    此时,则是为水果类声明了一个接口,表现在代码上:

     1  public   interface  Fruit {
     2      // 生长 
     3        void  grow();
     4       // 收获 
     5        void  harvest();
     6       // 种植 
     7        void  plant();
     8 
     9  
    10 


    水果接口规定出所有的水果必须实现的接口,包括任何水果类必须具备的方法plant(),grow(),和harvest();

    Apple类是水果类的一种,因此它实现了水果接口所声明的所有方法。另处,由于苹果是多年生植物,因此多出一个treeAge性质,描述苹果的树龄。代码如下所示:

     package  fac;

     public   class  Apple  implements  Fruit { // 通过implements实现接口Fruit 
          private   int  treeAge;
        
         public   void  grow() {
            log( " Apple is growing " );
        } 
        
         public   void  harvest() {
            log( " Apple has been harvested " );
        } 
        
         public   void  plant() {
            log( " Apple ha been planted " );
        } 
        
         public   static   void  log(String msg) {
            System.out.println(msg);
        } 
        
         public   int  getTreeAge() {
             return  treeAge;
        } 
        
         public   void  setTreeAge( int  treeAge) {
             this .treeAge = treeAge;
        } 


    同理,葡萄 Grape:

    package fac;

    public class Grape implements Fruit{
        private boolean seedless;
        public void grow(){
            log("Grape is growing.");
        }
        
        public void harvest(){
            log("Grape has been harvested");
        }
        
        public void plant(){
            log("Grape ha been planted");
        }
        
        public static void log(String msg){
            System.out.println(msg);
        }

        public boolean isSeedless() {
            return seedless;
        }

        public void setSeedless(boolean seedless) {
            this.seedless = seedless;
        }
        

    }


    草莓 Stuawberry:

    package fac;

    public class Strawberry implements Fruit{
        public void grow(){
            log("Strawberry is growing");
        }
        
        public void harvest(){
            log("Strawberry has been harvested");
        }
        
        public void plant(){
            log("Strawberry has been planted");
        }
        
        public static void log(String msg){
            System.out.println(msg);
        }
    }



    农场园丁也是系统的一部分,由一个类来代表,FruitGardener类,代码如下:

    package fac;

    public class FruitGardener{
        public static Fruit factory(String which)throws Exception{
            if(which.equalsIgnoreCase("apple")){
                return new Apple();
            }else if(which.equalsIgnoreCase("strawberry")){
                return new Strawberry();
            }else if (which.equalsIgnoreCase("grape")){
                return new Grape();
            }else{
                throw new Exception("Bad fruit request");
            }
        }
    }

    这时有人来果园玩,和园丁说,给我们介绍下你的水果吧。于是园丁:

    package fac;

    public class People {

        public static void main(String[] args) throws Exception {
            FruitGardener fg=new FruitGardener();
            Fruit ap=fg.factory("Apple");
            ap.grow();
            Fruit gp=fg.factory("Grape");
            gp.plant();
            
            Fruit dd=fg.factory("ddd");//抛出Bad fruit request异常
        }    

    }


    (注:以上代码在JDK5.0,Myeclise3.2下编译通过)

     类比两个例子,园丁就相当于女娲,而水果就相当于具体的人,接口水果类就相当于存在于类女娲思想里的人的抽象概念。

    由以上两个例子可得出,简单工厂模式需要由以下角色组成:
          接口
                            接口的实现类(简单工厂模式里面的具体产品角色)
                            工厂

    理解了以下两个例子,再来看第三个例子:
    注意对比以下三个实例的不同
    实例1:

    package org.jzkangta.factorydemo01;
    //定义接口
    interface Car{
        public void run();
        public void stop();
    }
    //具体实现类
    class Benz implements Car{
        public void run(){
            System.out.println("Benz开始启动了。。。。。");
        }
        public void stop(){
            System.out.println("Benz停车了。。。。。");
        }
    }
    //具体实现类
    class Ford implements Car{
        public void run(){
            System.out.println("Ford开始启动了。。。");
        }
        public void stop(){
            System.out.println("Ford停车了。。。。");
        }
    }
    //工厂
    class Factory{
        public static Car getCarInstance(){
            return new Ford();
        }
    }
    public class FactoryDemo01 {

        public static void main(String[] args) {
            Car c=Factory.getCarInstance();
            c.run();
            c.stop();

        }

    }


    实例二:

    package fac;


    //定义接口
    interface Car{
        public void run();
        public void stop();
    }
    //具体实现类
    class Benz implements Car{
        public void run(){
            System.out.println("Benz开始启动了。。。。。");
        }
        public void stop(){
            System.out.println("Benz停车了。。。。。");
        }
    }

    class Ford implements Car{
        public void run(){
            System.out.println("Ford开始启动了。。。");
        }
        public void stop(){
            System.out.println("Ford停车了。。。。");
        }
    }
    //工厂
    class Factory{
        public static Car getCarInstance(String type){
            Car c=null;
            if("Benz".equals(type)){
                c=new Benz();
            }
            if("Ford".equals(type)){
                c=new Ford();
            }
            return c;
        }
    }


    public class FactoryDemo02 {

        public static void main(String[] args) {
            Car c=Factory.getCarInstance("Benz");
            if(c!=null){
                c.run();
                c.stop();
            }else{
                System.out.println("造不了这种汽车。。。");
            }
            

        }

    }


    实例三:

    interface Car{
        public void run();
        public void stop();
    }

    class Benz implements Car{
        public void run(){
            System.out.println("Benz开始启动了。。。。。");
        }
        public void stop(){
            System.out.println("Benz停车了。。。。。");
        }
    }

    class Ford implements Car{
        public void run(){
            System.out.println("Ford开始启动了。。。");
        }
        public void stop(){
            System.out.println("Ford停车了。。。。");
        }
    }

    class Toyota implements Car{
        public void run(){
            System.out.println("Toyota开始启动了。。。");
        }
        public void stop(){
            System.out.println("Toyota停车了。。。。");
        }
    }

    class Factory{
        public static Car getCarInstance(String type){
            Car c=null;
            try {
                c=(Car)Class.forName("org.jzkangta.factorydemo03."+type).newInstance();//利用反射得到汽车类型 
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        
            return c;
        }
    }
    public class FactoryDemo03 {

        public static void main(String[] args) {
            Car c=Factory.getCarInstance("Toyota");
            if(c!=null){
                c.run();
                c.stop();
            }else{
                System.out.println("造不了这种汽车。。。");
            }
            

        }

    }



    对比三个实例:
    实例一,虽然实现了简单工厂,但每次只能得到一种汽车,如果我们想换一种,就得修改工厂,太不方便,而实例二则改变了这种情况,便得我们可以按照我们的需要更换汽车,但我们所更换的汽车必须是实现类中有的,如果我们想要增加一种汽车的时候,我们还是得更改工厂,通过改进,实例三利用反射机制,得到汽车类型,这样当我们需要增加一种新的汽车时,就无需要再修改工厂,而只需要增加要实现的类即可。也就是说要增加什么样的汽车直接增加这个汽车的类即可,而无需改变工厂。从而达到了工厂分离的效果。

    但是为什么不能访问苹果中的set  get  treeage 方法呢??

    自己重新new出来的apple 对象则可以访问 set get方法??why

  • 相关阅读:
    LeetCode偶尔一题 —— 617. 合并二叉树
    《剑指offer》 —— 链表中倒数第k个节点
    《剑指offer》 —— 青蛙跳台阶问题
    《剑指offer》—— 二维数组中的查找
    《剑指offer》—— 替换空格
    《剑指offer》—— 合并两个排序的链表
    《剑指offer》—— 礼物的最大价值
    生成Nuget 源代码包来重用你的Asp.net MVC代码
    Pro ASP.Net Core MVC 6th 第四章
    Pro ASP.NET Core MVC 6th 第三章
  • 原文地址:https://www.cnblogs.com/wuyun-blog/p/4522850.html
Copyright © 2011-2022 走看看