zoukankan      html  css  js  c++  java
  • 工厂模式

    先说下我对工厂模式的理解:当我们需要某个对象时,最直接的办法是看到这个对象就拿过来。但是当对象非常多的时候,找起来就很不方便。这时就需要一个中介来帮助我们取得想要的东西,这个中介就是工厂(factory)。

    工厂模式可分为三个分类(简单工厂模式Simple Factory、 工厂方法模式Factory Method、 抽象工厂模式Abstract Factory)

    我来模拟一个场景:动物园管理员每天都要确保动物的健康,确定动物健康的一种简单方法就是听一听动物的叫声是不是正常。这样,管理员就需要随时找到任一种动物以确定动物的情况。下面是动物相关类(至于动物园为什么有猫和狗大家就不要太计较了……):

    interface:Animal(动物的接口)

    package com.captain.factory;
    /**
     * <P>Title:动物接口<p>
     * @author 船长工作室
     */
    public interface Animal {
        void call();
    }
    package com.captain.factory;
    
    /**
     * <p>Title:猫<p>
     * @author 船长工作室
     */
    public class Cat implements Animal {
        /**
         * 猫叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("meow");
        }
    
    }
    
    package com.captain.factory;
    /**
     * <p>Title:狗<p>
     * @author 船长工作室
     */
    public class Dog implements Animal {
        /**
         * 狗叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("bark");
        }
    
    }
    
    package com.captain.factory;
    /**
     * <p>Title:老虎<p>
     * @author 船长工作室
     */
    public class Tiger implements Animal {
        /**
         * 老虎叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("roar");
        }
    
    }

    下面先介绍简单工厂模式:

    class:SimpleFactory(简单工厂)

    package com.captain.factory;
    /**
     * <p>Title:简单工厂模式-工厂类<p>
     * @author 船长工作室
     */
    public class SimpleFactory {
        /**
         * 召唤动物
         * @param s 召唤动物的种类
         * @return animal 该种类的动物实例
         */
        public static Animal search(String s){
            Animal animal = null;
            if ("cat".equals(s)){//判断召唤动物的种类
                animal = new Cat();
            }else if("dog".equals(s)){
                animal = new Dog();
            }else if("tiger".equals(s)){
                animal = new Tiger();
            }
            return animal;//返回找到的动物
        }
    }
    package com.captain.factory;
    
    /**
     * <p>Title:简单工厂模式-动物管理员<p> 
     * @author 船长工作室
     */
    public class SimpleManager {
        /**
         * 动物管理员找到所需动物,并让该动物叫出声来
         * @param args
         */
        public static void main(String[] args) {
            Animal animal = SimpleFactory.search("dog");//从工厂中获得指定类型动物
            if ( animal == null ){
                System.out.print("can't find this kind of animal!");
                return;//没有找到指定动物,返回
            }
            animal.call();//让得到的动物叫出声来
        }
    }

    简单工厂通过一个工厂对象来管理、查询各个对象。比较简单、方便。但是当添加新的动物时,我们不仅要添加新的动物类,还要修改工厂中的逻辑(if()...else if()...else if()...)。当逻辑比较复杂时,就会很混乱……

    工厂方法模式就解决了这个问题:

    Interface:CallAnimal(召唤动物)

    package com.captain.factory;
    /**
     * <p>Title:召唤动物接口<p>
     * @author 船长工作室
     */
    public interface CallAnimal {
        /**
         * 得到召唤的动物
         * @return Animal 召唤的动物
          */
        Animal callAnimal();
    }
    
    package com.captain.factory;
    
    /**
     * <p>Title:得到猫<p>
     * @author 船长工作室
     */
    public class CallCat implements CallAnimal {
        /**
         * 得到猫 
         * @return Cat 猫
         */
        public Animal callAnimal() {
            return new Cat();
        }
    
    }
    package com.captain.factory;
    
    /**
     * <p>Title:得到狗<p>
     * @author 船长工作室
     */
    public class CallDog implements CallAnimal {
        /**
         * 得到狗 
         * @return Dog 狗
         */
        public Animal callAnimal() {
            return new Dog();
        }
    
    }
    
    package com.captain.factory;
    
    /**
     * <p>Title:得到老虎<p>
     * @author 船长工作室
     */
    public class CallTiger implements CallAnimal {
        /**
         * 得到老虎 
         * @return Tiger 老虎
         */
        public Animal callAnimal() {
            return new Tiger();
        }
    
    }
    
    package com.captain.factory;
    /**
     * <p>Title:工厂方法模式-动物管理员<p>
     * @author 船长工作室
     */
    public class MethodManager {
        /**
         * 动物管理员通过指定工厂找到所需动物,并让该动物叫出声来
         * @param args
         */
        public static void main(String[] args){
            CallAnimal callAni = new CallCat();//调用指定动物工厂
            Animal animal = callAni.callAnimal();//获得指定
            animal.call();//让动物叫
        }
    }

    工厂方法模式通过一个工厂一个对象的形式,解决了上述问题。当需要一个新的对象时,只需新建一个对应的工厂,并在使用时调用相应的工厂就好了。但是这种方式会随着对象的增加而出项很多很多的工厂对象……

    下面介绍抽象工厂模式:

    我认为抽象工厂模式适用于有分类的情况。比如HP、DELL、Lenov都有台式机和笔记本、智能手机出售。这时可以为每个品牌建立一个工厂,工厂里得到该品牌的产品(台式机、笔记本、智能手机)。想买什么产品,将调用相应品牌的对应方法,得到该产品。

    还以我们的动物园管理员举例。现在我们的管理员需要对动物按性别进行管理。这样,我们就需要建立雄性和雌性两个接口。

    Interface:Male(雄性)

    package com.captain.factory;
    /**
     * <p>Title:雄性<p>
     * @author 船长工作室
     */
    public interface Male {
    
    }
    
    package com.captain.factory;
    /**
     * <p>Title:雌性<p>
     * @author 船长工作室
     */
    public interface Female {
    
    }
    
    package com.captain.factory;
    /**
     * <p>Title:公猫<p>
     * @author 船长工作室
     */
    public class MaleCat extends Cat implements Male{
        /**
         * 公猫叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("male-meow");
        }
    }
    
    package com.captain.factory;
    /**
     * <p>Title:公狗<p>
     * @author 船长工作室
     */
    public class MaleDog extends Dog implements Male{
        /**
         * 公狗叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("male-bark");
        }
    }
    
    package com.captain.factory;
    /**
     * <p>Title:公老虎<p>
     * @author 船长工作室
     */
    public class MaleTiger extends Tiger implements Male{
        /**
         * 公老虎叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("male-roar");
        }
    }
    
    package com.captain.factory;
    /**
     * <p>Title:母猫<p>
     * @author 船长工作室
     */
    public class FemaleCat extends Cat implements Female{
        /**
         * 母猫叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("female-meow");
        }
    }
    
    package com.captain.factory;
    /**
     * <p>Title:母狗<p>
     * @author 船长工作室
     */
    public class FemaleDog extends Dog implements Female{
        /**
         * 母狗叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("female-bark");
        }
    }
    
    package com.captain.factory;
    /**
     * <p>Title:母老虎<p>
     * @author 船长工作室
     */
    public class FemaleTiger extends Tiger implements Female{
        /**
         * 母老虎叫
         * @param 无
         * @return void
         */
        public void call() {
            System.out.print("female-roar");
        }
    }

    分类完毕之后,我们需要定义一个工厂接口,这个接口能够获得所有种类的对象(比如猫、狗、老虎)

    Interface:AbstractFactory(抽象工厂)

    package com.captain.factory;
    /**
     * <p>Title:抽象工厂<p>
     * @author 船长工作室
     */
    public interface AbstractFactory {
        /**
         * 获得猫
         * @return*/
        Cat callCat();
        
        /**
         * 获得狗
         * @return*/
        Dog callDog();
        
        /**
         * 获得老虎
         * @return 老虎
         */
        Tiger callTiger();
    }
    
    有了接口,我们要实现两个具体工厂(分别是公的和母的……)
    
    class:MaleFactory(雄性工厂)
    
    
    package com.captain.factory;
    /**
     * 获得雄性动物
     * @author 船长工作室
     */
    public class MaleFactory implements AbstractFactory {
        /**
         * 获得公猫
         * @return 公猫
         */
        public Cat callCat() {
            return new MaleCat();
        }
    
        /**
         * 获得公狗
         * @return 公狗
         */
        public Dog callDog() {
            return new MaleDog();
        }
    
        /**
         * 获得公老虎
         * @return 公老虎
         */
        public Tiger callTiger() {
            return new MaleTiger();
        }
    }
    
    class:FemaleFactory(雌性工厂)
    
    package com.captain.factory;
    /**
     * 获得雌性动物
     * @author 船长工作室
     */
    public class FemaleFactory implements AbstractFactory {
        /**
         * 获得母猫
         * @return 母猫
         */
        public Cat callCat() {
            return new FemaleCat();
        }
    
        /**
         * 获得母狗
         * @return 母狗
         */
        public Dog callDog() {
            return new FemaleDog();
        }
    
        /**
         * 获得母老虎
         * @return 母老虎
         */
        public Tiger callTiger() {
            return new FemaleTiger();
        }
    }
    
    
    有了以上两个工厂,我们就可以获得其中一种性别的动物了
    
    class:AbstractManager(动物园管理员)
    
    package com.captain.factory;
    
    /**
     * <p>Title:抽象工厂模式-动物管理员<p> 
     * @author 船长工作室
     */
    public class AbstractManager {
        /**
         * 动物管理员找到所需动物,并让该动物叫出声来
         * @param args
         */
        public static void main(String[] args) {
            FemaleFactory maleFac = new FemaleFactory();//建立雌性动物工厂
            Animal animal = maleFac.callTiger();//从工厂中获得指定类型动物
            if ( animal == null ){
                System.out.print("can't find this kind of animal!");
                return;//没有找到指定动物,返回
            }
            animal.call();//让得到的动物叫出声来
        }
    }

    可见,管理员通过建立雌性动物工厂,得到了母老虎……

    采用抽象工厂时,有几个分类就有几个工厂(HP、DELL、Lenovo等),每个工厂里,有几种产品就有几个方法(createDesktop、createNotebook、createPhone等)。

  • 相关阅读:
    Unity中Avatar换装实现
    Unity 导出NavMesh (可行走区域判定) 数据给服务器使用
    Unity发布安卓Splash Image适应手机、平板
    什么是展uv
    三合一收款二维码
    牛顿的八字养生经
    牛顿
    [家里蹲大学数学杂志]第412期积分与极限
    Newton's Dark Secrets《牛顿探索》
    英国《物理世界》杂志评选出世界十大物理学家
  • 原文地址:https://www.cnblogs.com/liangjq/p/4007052.html
Copyright © 2011-2022 走看看