java工厂模式,工厂模式和抽象工厂模式的区别

发布时间:2023-01-09

本文目录一览:

  1. Java的工厂模式有哪一些,分别有什么作用,一般用在哪些地方?
  2. Java中常用的设计模式有哪些?请详细说明一下工厂模式。
  3. java策略模式和工厂模式的区别
  4. 用java 编写程序写出简单的工厂模式?
  5. java工厂模式,懂的人进

Java的工厂模式有哪一些,分别有什么作用,一般用在哪些地方?

我简单的说下,举个例子,当我们的程序结构比较繁杂时,比如有100个类,而类中又有很多方法,这些方法之间都互相有依赖关系,也就是一个方法之间的某段逻辑处理需要用到另一个类中的代码逻辑,这种时候对于整个程序而言是非常不利于开发的(我们需要考虑到很多类、方法之间的耦合问题),那么就有一个概念了,也就是面对接口编程。通俗的说就是把类中的方法封装起来,外部调用的人完全不需要考虑方法是如何实现的,但是这样做也有一个不好的地方,我们的接口是不提供方法实现的,而需要在类中实现接口的方法。那么问题产生了,我们在new接口对象的时候需要明确的知道他的实例类。 想象一下,如果程序在继续庞大,接口非常多,接口实例类非常多,这样又会产生我们之前的问题(我们需要考虑到很多类、方法之间的耦合问题)那么这个时候就产生了一中设计思想,也就是工厂模式,这种模式的核心思想就是管理接口的实例对象,把接口和实例对象之间的关系封装起来处理,外部需要用到某个接口的实例时,由工厂进行分配,而不需要关注具体是哪个实例。 如果你做到比较复杂的程序时你应该就能体会到了。

Java中常用的设计模式有哪些?请详细说明一下工厂模式。

  1. 单例模式(有的书上说叫单态模式其实都一样) 该模式主要目的是使内存中保持1个对象
  2. 工厂模式 该模式主要功能是统一提供实例对象的引用。看下面的例子:
    public class Factory{
        public ClassesDao getClassesDao(){
            ClassesDao cd = new ClassesDaoImpl();
            return cd;
        }
    }
    interface ClassesDao{
        public String getClassesName();
    }
    class ClassesDaoImpl implements ClassesDao {
        public String getClassesName(){
            System.out.println("A班");
        }
    }
    class test {
        public static void main(String[] args){
            Factory f = new Factory();
            f.getClassesDao().getClassesName();
        }
    }
    
    这个是最简单的例子了,就是通过工厂方法通过接口获取对象的引用
  3. 建造模式 该模式其实就是说,一个对象的组成可能有很多其他的对象一起组成的,比如说,一个对象的实现非常复杂,有很多的属性,而这些属性又是其他对象的引用,可能这些对象的引用又包括很多的对象引用。封装这些复杂性,就可以使用建造模式。
  4. 门面模式 这个模式个人感觉像是Service层的一个翻版。比如Dao我们定义了很多持久化方法,我们通过Service层将Dao的原子方法组成业务逻辑,再通过方法向上层提供服务。门面模式道理其实是一样的。
  5. 策略模式 这个模式是将行为的抽象,即当有几个类有相似的方法,将其中通用的部分都提取出来,从而使扩展更容易。

java策略模式和工厂模式的区别

  • 工厂模式是创建型模式
  • 策略模式是行为性模式
  • 一个关注对象创建
  • 一个关注行为的封装 策略模式就是定义一系列的算法,这些算法可以在需要的时候替换和扩展.工厂模式是生成型的模式,在你需要的时候构建具体的实例. 在下面的情况下应当考虑使用策略模式:
  1. 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
  2. 一个系统需要动态地在几种算法中选择一种。那么这些算法可以包装到一个个的具体算法类里面,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,由于多态性原则,客户端可以选择使用任何一个具体算法类,并只持有一个数据类型是抽象算法类的对象。
  3. 一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端涉及到不必要接触到的复杂的和只与算法有关的数据。
  4. 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象设计的概念。

策略模式的优点和缺点

策略模式有很多优点和缺点。它的优点有:

  1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
  2. 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
  3. 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。 策略模式的缺点有:
  4. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
  5. 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。 策略模式与很多其它的模式都有着广泛的联系。Strategy很容易和Bridge模式相混淆。虽然它们结构很相似,但它们却是为解决不同的问题而设计的。Strategy模式注重于算法的封装,而Bridge模式注重于分离抽象和实现,为一个抽象体系提供不同的实现。Bridge模式与Strategy模式都很好的体现了"Favor composite over inheritance"的观点。

用java 编写程序写出简单的工厂模式?

java中工厂模式分为:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory) 每种方法的实现不同 提供一个简单工厂模式的案例:
public abstract class Woman {
    private String mySkill;
    public String getMySkill() {
        return mySkill;
    }
    public Woman() {
        //System.out.println("我是女人");
    }
    public void setMySkill(String mySkill) {
        this.mySkill = mySkill;
    }
}

public class LovelinessWoman extends Woman{
    /* 可爱型女人 */
    public LovelinessWoman() {
        String mySkill="撒过娇、出过轨、勾引领导下过水";
        this.setMySkill(mySkill);
    }
}

public class SteelinessWoman extends Woman{
    /* 冷酷型女人 */
    public SteelinessWoman() {
        String mySkill="装过神、弄过鬼,跟别人老公亲过嘴";
        this.setMySkill(mySkill);
    }
}

public class WomanMakeFactory {
    public Woman findWoman(int typeID) {
        switch (typeID) {
            case 1:
                return new LovelinessWoman();
            case 2:
                return new VirtuousWoman();
            case 3:
                return new SteelinessWoman();
            default:
                return null;
        }
    }
    public Woman findWoman(String type) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        String string="cn.jbit.design.simplefactory."+type;
        Class c = Class.forName(string);
        Woman wm = (Woman) c.newInstance();
        return wm;
    }
}

调用:

public class Test2 {
    /** 
     * @param args
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Scanner input=new Scanner(System.in);
        boolean sel=false;
        do {
            System.out.println("请选择你要找的女人的类型");
            System.out.println("LovelinessWoman:可爱型女人 VirtuousWoman:善良型女人 SteelinessWoman:冷酷型女人");
            String typeid=input.next();
            WomanMakeFactory factory = new WomanMakeFactory();
            Woman wm=factory.findWoman(typeid);
            System.out.println("该类型女人的新标准:");
            System.out.println(wm.getMySkill());
            System.out.println("还想看看别的类型吗?y代表想,n代表再也不想了");
            sel=input.next().equals("y");
        } while (sel);
    }
}

java工厂模式,懂的人进

举两个例子以快速明白Java中的简单工厂模式: 女娲抟土造人 话说:“天地开辟,未有人民,女娲抟土为人。”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面。 女娲造人,这就是简单工厂模式的应用。 首先,在这个造人的思想里面,有几个重要的角色:女娲本身、抽象的人的概念和女娲所造出的一个个具体的人。

  1. 女娲是一个工厂类,也就是简单工厂模式的核心角色。
  2. 具休的一个个的人,包括张三,李四等。这些人便是简单工厂模式里面的具体产品角色
  3. 抽象的人是最早只存在于女娲的头脑里的一个想法,女娲按照这个想法造出的一个个具体的人,便都符合这个抽象的人的定义。换言之,这个抽象的想法规定了所有具体的人必须都有的接口(特征或者功能) 其UML类图出下所示: 理解了上面的这些东西,再来理解下面的例子,对照理解,相信看完这篇文章,便对java简单工厂模式有一个很好的理解: 有一个农场公司,专门向市场销售各类水果,在这个系统里需要描述下列水果:
  • 葡萄 Grape
  • 草莓 Stuawberry
  • 苹果 Apple 水果与其他植物不同,最终可以采摘食用,那么一个自然的做法是建立一个各种水果都适用的接口,以便与其他农场里的植物区分开来,在此时,则是为水果类声明了一个接口,表现在代码上:
public interface Fruit {
    // 生长
    void grow();
    // 收获
    void harvest();
    // 种植
    void plant();
}

水果接口规定出所有的水果必须实现的接口,包括任何水果类必须具备的方法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;
    }
}

草莓 Strawberry:

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) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            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("造不了这种汽车。。。");
        }
    }
}

对比三个实例:

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