工厂模式

工厂模式

就是工厂---生产-->产品

在设计模式中,分为 简单工厂模式, 工厂方法模式,抽象工厂模式.

工厂模式,就是:
提供创建对象的功能,不需要关心具体实现.

类似于,接口隔离(模块和模块):不需要知道具体的构建过程,就能得到相应的结果.
例如,
Bitmap bitmap=BitmapFactory.decodeXXX();
decodeXXX 其实是创建了不同的bitmap.不用关心如何生产出bitmap

简单工厂:

以生产 二维图形 为例.

  1. 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。

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

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

类图

代码实现

1.产品抽象类

public class Shape {
   /** @pdOid 6679a38e-beee-4da3-8749-c03329cfd976 */
   public void sayHello() {
      // TODO: implement
       
   }

}

2.产品实体类

public class Circle extends Shape {
   /** @pdOid 2abc7174-03ad-4365-8fff-3265612a3185 */
   private int radium;
   
   /** @pdOid b39ccef4-0987-473b-8e7d-1b8959c50985 */
   public void sayHello() {
       
       System.out.println("Hello, I am Circle from ShapeFactory!My address is "+this.hashCode());
   }

}

public class Traingle extends Shape {
   /** @pdOid 4911552c-ce2f-41e3-8a8f-d342dd482e50 */
   private int high;
   /** @pdOid 519ef847-62d8-435b-89a7-234c2fb5fcba */
   private int bottom;
   
   /** @pdOid 433ff6ef-9fbc-44f2-b159-97d17c6153a6 */
   public void sayHello() {
      // TODO: implement
       System.out.println("Hello, I am Traingle from ShapeFactory! My address is "+this.hashCode());
   }

}

3.图形工厂类(包括缓存模式)

public class ShapeFactory {

    
   private static HashMap<String,Shape> shapeMap=new HashMap<>();
   
    /**
     * 简单工厂创建
     * @param type Traingle创建三角形traingle,Circle创建圆形Circle
     * @return Shape
     */
    public static Shape create(String type) {
        Shape shape = null;
        switch (type) {
        case "Traingle":
            //
            shape=new Traingle();
            break;
        case "Circle":
            shape=new Circle();
            break;
        default:
            break;
        }
        return shape;
    }

    /**
     * 简单工厂创建---单例缓存
     * @param type Traingle创建三角形traingle,Circle创建圆形Circle
     * @return Shape
     */
    public static Shape createSingle(String type) {
        Shape shape = null;
        switch (type) {
        case "Traingle":
            shape = getSingleFromMap(type);
            break;
        case "Circle":
            shape = getSingleFromMap(type);
            break;
        default:
            break;
        }
        return shape;
    }

    private static Shape getSingleFromMap(String type) {
        Shape shape;
        if(shapeMap.get(type)==null){
            shape=new Traingle();
            shapeMap.put(type, shape);
        }else{
            shape=shapeMap.get(type);
        }
        return shape;
    }
    
    

    
}

测试类

public class Test {
    
    
    public static void main(String[] args) {
        System.out.println("============简单工厂模式==================");

        Shape traingle =ShapeFactory.create("Traingle");
        traingle.sayHello();
        Shape circle =ShapeFactory.create("Circle");
        circle.sayHello();
        Shape traingle3 =ShapeFactory.create("Traingle");
        traingle3.sayHello();
        Shape circle3 =ShapeFactory.create("Circle");
        circle3.sayHello();
        System.out.println("============简单工厂---缓存模式==================");
        
        Shape traingle1 =ShapeFactory.createSingle("Traingle");
        traingle1.sayHello();
        Shape circle1 =ShapeFactory.createSingle("Circle");
        circle1.sayHello();
        Shape traingle2 =ShapeFactory.createSingle("Traingle");
        traingle2.sayHello();
        Shape circle2 =ShapeFactory.createSingle("Circle");
        circle2.sayHello();
    }

}

工厂方法模式

是简单工厂模式的优化版,
有一个工厂抽象类,然后有很多具体的工厂.

当有新的产品需要生产时候,只需要新建一个具体工厂,就能生产,而不是在原来的工厂中,进行修改. 每个具体工厂类只能创建一个具体产品类的实例。 体现了修改关闭原则.

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

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

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

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

类图举例

代码实现

1.抽象产品类(同简单工厂)

2.具体产品类(同简单工厂)

3.一个抽象工厂类

public abstract class ShapeFactory {
   /** @pdOid 4a15aecb-010c-4d48-811a-92b793f6612b */
   public abstract Shape create();

}

4.多个具体工厂类


public class CircleFactory extends ShapeFactory {
   /** @pdOid ffffb088-9334-47a3-bfb8-f99ddd6c77a1 */
   public Shape create() {
      // TODO: implement
      return new Circle();
   }

public class TraingleFactory extends ShapeFactory {
   /** @pdOid 50f4544e-9c7a-407b-9478-247f45072997 */
   public Shape create() {
      // TODO: implement
      return new Traingle();
   }
   

}

5.测试类


public class Test {
    
    
    public static void main(String[] args) {
        
        System.out.println("==========工厂方法模式=========");
        
        ShapeFactory factory=new TraingleFactory();
        Shape shape=factory.create();
        shape.sayHello();
        ShapeFactory factory1=new CircleFactory();
        Shape shape1=factory1.create();
        shape1.sayHello();
    }
}

==========工厂方法模式=========

Hello, I am Traingle from ShapeFactory! My address is 366712642

Hello, I am Circle from ShapeFactory!My address is 1829164700

抽象工厂模式

抽象工厂模式: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。

类图

代码实现

1.抽象产品


public interface Color {
   /** @pdOid a12f0089-9a07-4426-8f7e-af49aa2a79bb */
   int fill();

}

public interface Shape {
   /** @pdOid 5a0c95e5-55e1-471e-a61a-740a673aece8 */
   int draw();

}

2.抽象工厂

public abstract class AbstractFactory {
   /** @pdOid 11ac6789-7964-4e4a-87a9-a64a69a506e5 */
   public abstract Color getColor(String type);
   /** @pdOid 3a57f707-a85a-4703-a3ff-084c6dd11587 */
   public abstract Shape getShape(String type);

}

3.实体工厂


public class ColorFactory extends AbstractFactory {
    /** @pdOid 4fb42edd-3722-4c38-9e14-86435450ccc1 */
    public Color getColor(String shapeType) {
        // TODO: implement
        if (shapeType.equals("Red")) {
            return new Red();
        } else if (shapeType.equals("Blue")) {
            return new Blue();

        }
        return null;
    }

@Override
public Shape getShape(String type) {
    // TODO Auto-generated method stub
    return null;
}

}

/** @pdOid 5f64c413-67bb-4255-9197-9fb9f9a6d502 */
public class ShapeFactory extends AbstractFactory {
   /** @pdOid 4e659634-78f7-48ae-9751-d3beaf5cc550 */
   public Shape getShape(String shapeType) {
        if (shapeType.equals("Traingle")) {
            return new Traingle();
        } else if (shapeType.equals("Circle")) {
            return new Circle();

        }
        return null;
   }

@Override
public Color getColor(String shapeType) {
    // TODO Auto-generated method stub
    return null;
}

}

4.创建工厂的驱动


public class FactoryCreator {

    public static AbstractFactory createFactory(String type){
        
        if (type.equals("Color")) {
            return new ColorFactory();
        } else if (type.equals("Shape")) {
            return new ShapeFactory();

        }
        return null;
        
        
        
    }
    
    
}

测试


public class Test {

    public static void main(String[] args) {
        
        
        System.out.println("==========抽象工厂模式=========");
        AbstractFactory factory = FactoryCreator.createFactory("Color");
        factory.getColor("Red").fill();
        
        System.out.println("==========极限调用.感觉好帅...=========");
        FactoryCreator.createFactory("Shape").getShape("Circle").draw();

    }
}


==========抽象工厂模式=========
Hello, I am Red from ColrFactory!My address is 366712642
==========极限调用.感觉好帅...=========
Hello, I am Circle from ShapeFactory!My address is 1829164700

工厂总结

简单工厂模式:

0.实体产品:产品是什么,能抽象成什么.

1.要知道要什么产品,将产品抽象话,作为抽象产品(产品抽象类),

2.建一个实体工厂,准备开工.

3.生产同一类产品的不同型号(就像同一种猪不同的大小,重量等).

优点:灵活,简单

工厂方法:

0.实体产品:产品是什么,能抽象成什么.

1.抽象产品:目前有一种类型,不同型号的产品(图形),

2.抽象工厂:工厂要做生产不同图形.

3.建立实体工厂:分别将要生产的同类型的产品,按照不同型号(三角形,圆形)分别创建工厂.由实 体工厂提供产品.

优势:以后如果想要生产一个不同的产品,就可以直接 创建产品实体,继承抽象工厂创建实体工厂,进行生产,而不修改其他,体现开闭原则

抽象工厂模式:

抽象二字,体现在 抽象工厂,抽象出要生产的产品种类.

当有多种产品的时候(多个产品族),可以考虑用抽象工厂模式,用一个抽象工厂(抽象出所需要的产品种类),然后用多个实体工厂(建造同族中不同的产品).

当有新的产品进入的时候,只需要添加抽象产品到抽象工厂,然后创建相应的工厂即可,
体现了依赖倒置原则 :依赖于抽象,依赖于抽象,即程序中所有的依赖关系都应该终止于抽象类或者接口.要针对接口编程,不针对实现编程。

优势:针对于多种产品,抽象出所需产品即可.

缺点:模式过于臃肿,添加产品要修改抽象工厂.

区别: 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

总而言之,
工厂模式,是利用封装,继承和多态属性,实现父类引用指向子类对象,进行依赖倒置,面向抽象和接口编程,实现同一父类下各个子类的互换,而客户端可以毫不察觉。进而达到 不需要知道具体的构建过程,就能得到相应的结果.并尽量保持对扩展开放,对修改关闭.

模式,就是模式,没有必要完全遵守,适时适地,灵活运用,才是根本..

自己愚见,未能深刻领悟,有不足之处,希望能一起探讨.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容