zoukankan      html  css  js  c++  java
  • Simple Factory 简单工厂模式(静态工厂)

    基本概念:

    1)  Simple Factory模式属于创建型模式,

    2)  简单工厂模式是由一个工厂(注意是一个!)对象决定创建出哪一种产品类的实例(例如你到肯德基说你要鸡腿,要薯条,要饮料还是,,,这时肯德基是一

    个工厂,客户端只需要点明自己要什么就行)

    3)实现方式的实质:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。 


    下面来看一个例子:


    音乐盒接口IMusicBox:

    package SimpleFactory;
    
    public interface IMusicBox {
        public void play();
    }

    两种不同的音乐盒播放方式:ViolinBox(小提琴)和 PianoBox(钢琴):

    package SimpleFactory;
    
    public class ViolinBox implements IMusicBox {
        public void play() {
            System.out.println("拨放小提琴音乐^_^");
        }
    }
    package SimpleFactory;
    
    public class PianoBox implements IMusicBox {
        
        public void play() {
            System.out.println("拨放钢琴音乐:)");
        }
    }

    下面是一个工厂MusicBoxFactory(Simple Factory的核心,在工厂中根据客户端指定的参数动态创建不同的对象):

    package SimpleFactory;
    
    public class MusicBoxFactory {
        
        public static IMusicBox createMusicBox(String name) 
                                   throws InstantiationException, 
                                         IllegalAccessException,
                                         ClassNotFoundException{
            
            // 这边使用的是Java的Reflection机制来产生实例
            // 不过客户端不用管啦
            // 以后就算改变了这边的程式,客户端程式是不用更改的
            return (IMusicBox) Class.forName(name).newInstance();
           
        }
    }

    下面客户端就可以利用工厂模式:(利用工厂模式,客户端只需要对工厂指定你要创建的对象的名字(参数),工厂就可以根据你指定的参数动态创建不同的对象)

    package SimpleFactory;
    
    public class MusicBoxDemo {
        
        public static void main(String[] args) throws Exception {
           // playMusicBox(MusicBoxFactory.createMusicBox("PianoBox"));
           // playMusicBox(MusicBoxFactory.createMusicBox("ViolinBox"));
            
            //利用工厂模式,客户端只需要对工厂指定你要创建的对象的名字(参数),工厂就可以根据你指定的参数动态
            //创建不同的对象。当然,这些不同的对象就有不同的表现(在本例中通过play表示)
            playMusicBox(MusicBoxFactory.createMusicBox("SimpleFactory.PianoBox"));
            playMusicBox(MusicBoxFactory.createMusicBox("SimpleFactory.ViolinBox"));
        }
        
        public static void playMusicBox(IMusicBox musicBox) {
            musicBox.play();
        }
    }

    结果:

    拨放钢琴音乐:)
    拨放小提琴音乐^_^


    上面例子的关系用下图表示:



    -------------------------------------------------------------------------------------------------------------------------------------------------



    分析:

    工厂角色:被客户端直接调用,根据客户端指定传入的参数,动态创建客户端需要的对象

    抽象产品角色:所有对象的父类(接口)

    具体产品角色:即工厂的创建目标,工厂创建的对象就是这些具体类的对象。


    可以看出,客户端只面对工厂,不用管产品的具体细节,客户只需向工厂要求你需要什么,其他的事情都交给工厂了。



    优点:

    通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各

    自的职责和权利。(简单地说,你到肯德基去只需要说你要鸡腿还是鸡翅就行了,不需要去管鸡腿和鸡翅是怎么做出来的,工厂为你提供了这样一个界面)

    不足:

    由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新

    的类,则就需要改变工厂类了。

    当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模

    块功能的蔓延,对系统的维护和扩展非常不利; 


    使用场景

      工厂类负责创建的对象比较少;   

      客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;  

      由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。


    从上面的例子也可以看出来,工厂类往往是用反射机制来产生具体对象的。(因为不同类都继承自同一接口),故其扩展性很有限,产品种类必须是事先就知道的哪几

    种,什么时候你想要添加一个不是公共接口下的具体类就不行了。

    另外,如果你不用反射机制,也不要公共接口,在工厂中使用其他逻辑(例如判断传入的字符串)来根据用户参数创建对象也行,那样扩展性也是很糟糕的,逻辑和添

    加只会越来多。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 黑色星期五
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 比赛安排
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 斜率计算
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    Java实现 蓝桥杯VIP 算法训练 整数平均值
    控件动态产生器(使用RegisterClasses提前进行注册)
    Delphi编写自定义控件以及接口的使用(做了一个TpgDbEdit)
    Log4delphi使用心得
  • 原文地址:https://www.cnblogs.com/beautiful-code/p/5006404.html
Copyright © 2011-2022 走看看