zoukankan      html  css  js  c++  java
  • [设计模式]工厂模式

    我现在有一个动物的继承体系:
    Animal
    所有的动物都要吃饭.
    |--Pig
    |--Dog

    当创建对象比较简单的时候,我们就可以直接在main方法里面做了,但是,很多时候,创建对象可能还需要做一些初始化,
    也就是说创建对象的操作会比较复杂,这个时候,如果所有对象的创建工作我们还是在main里面就不太合适.

    怎么解决这个问题呢?
    通过一个简单的工厂给解决了.

    简单工厂优点和缺点:
    对象的创建比较复杂的时候,就考虑使用工厂来实现.

    优点:在简单工厂模式中,客户端不再负责对象的创建,而是把这个责任交给了工厂类.
    客户端只负责对象的调用,从而明确了各个类的职责.(单一职责)
    缺点:由于这个工厂类负责的所有对象的创建,那么,当子类不断增多的时候,我们就需要
    去修改工厂的代码,这样呢,就违反了一个原则:开闭原则.
    (假如真的要创建一个cat,工厂是没有创建cat的功能的.现实情况可能真的有创建cat的需求的,所以这个时候就需要
    更改工厂类中的创建对象的方法,就违反了一个原则:开闭原则.一个对象对扩展开放对修改关闭.如果修改的话可能对其他地方会有 影响.)

    这个时候怎么办呢?
    这个时候就采用另外一种模式:工厂方法模式.

    简单工厂模式代码:

    Animal.java

    1 /*
    2  * 这是一个抽象的动物类
    3  * 里面有一个吃的功能
    4  */
    5 public abstract class Animal {
    6     public abstract void eat();
    7 }

    Pig.java

    1 public class Pig extends Animal {
    2     public void eat() {
    3         System.out.println("猪吃饲料");
    4     }
    5 }

    Dog.java

    1 public class Dog extends Animal {
    2     public void eat() {
    3         System.out.println("狗啃骨头");
    4     }
    5 }

    AnimalFactory.java

     1 /*
     2  * 提供一个动物工厂类
     3  */
     4 public class AnimalFactory {
     5     //写一个功能,返回一个Dog对象即可.
     6     public static Dog createDog(){
     7         //即使这里面的创建动作很复杂,但是也不需要客户端来管理.
     8         //这些复杂的事情都在工厂里面给做好了.
     9         //Dog d = new Dog();
    10         //return  d;
    11         
    12         return new Dog();
    13     }
    14     public static Pig createPig(){
    15         return new Pig();
    16     }
    17     /**
    18      * 根据不同类型的字符串来创建不同的对象.
    19      * @param type 不同类型的字符串
    20      * @return 对应的字符串.
    21      */
    22     public static Animal createAnimal(String type){
    23         if("pig".equals(type)){
    24             return new Pig();
    25         }else if("dog".equals(type)){
    26             return new Dog();
    27         }
    28         return null;
    29     }
    30 }

    AnimalTest.java

     1 /*
     2  *动物的测试
     3  */
     4 public class AnimalTest {
     5     public static void main(String[] args) {
     6         /*
     7         //创建对象
     8         Dog d = new Dog();
     9         d.eat();
    10         Pig p = new Pig();
    11         p.eat();
    12         */
    13         
    14         /*
    15         //当工厂出现后,怎么测试Dog类呢?
    16         Dog d = AnimalFactory.createDog();
    17         d.eat();
    18         
    19         //调用的对象直接交给了工厂去创建.
    20         Pig p= AnimalFactory.createPig();
    21         p.eat();
    22         */
    23         //Dog d = AnimalFactory.createAnimal("dog");
    24         //上面这句话是会报错的createAnimal()这个返回的是一个Animal类型,不用用子类Dog去接受
    25         //要用父类去接收这个就是多态.
    26         Animal d = AnimalFactory.createAnimal("dog");
    27         d.eat();
    28         
    29         Animal p = AnimalFactory.createAnimal("pig");
    30         p.eat();
    31         
    32         //报空指针异常.NullPointerException
    33         //开发中:针对对象,我们一般判断是否为nul,如果不为空再使用.
    34         Animal c = AnimalFactory.createAnimal("cat");
    35         if(c!=null){
    36             c.eat();
    37         }
    38     }    
    39 }
  • 相关阅读:
    SwiftUI:看我展示52张扑克牌,“很快啊!”
    不会吧,这也行?iOS后台锁屏监听摇一摇
    分布式锁
    布隆过滤器原理
    redis缓存穿透
    布隆过滤器应用DEMO
    线程的声明周期
    分布式事务
    滑动窗口协议
    代理
  • 原文地址:https://www.cnblogs.com/DreamDrive/p/4084289.html
Copyright © 2011-2022 走看看