码迷,mamicode.com
首页 > 其他好文 > 详细

工厂模式

时间:2014-10-05 16:32:58      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   使用   ar   sp   div   问题   

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

 

工厂模式

标签:des   style   blog   color   使用   ar   sp   div   问题   

原文地址:http://www.cnblogs.com/liangjq/p/4007052.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!