zoukankan      html  css  js  c++  java
  • Java中的工厂模式

    设计模式遵循原则

    • 开闭原则:对扩展开放,对修改关闭
    • 里氏代换原则:只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被覆用。而衍生类也能够在基类的基础上增加新的行为
    • 依赖倒转原则:开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体
    • 接口隔离原则:使用多个隔离的接口来降低耦合度
    • 迪米特法原则:最少知道原则。一个实体应该尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立
    • 合成复用原则:尽量使用合成/聚合的方式,而不是使用继承。继承实际上破环了类的封装性,超类的方法可能会被子类修改。

    工厂模式

    简单工厂模式

    简单工厂模式当中,一个工厂负责生产所有的产品。如上图所示,无论是戴尔鼠标还是惠普鼠标,都在一家鼠标工厂中生产。工厂通过用户的需要生产不同的鼠标,即用户传入生产鼠标的参数,工厂返回生产出的鼠标实体。

    具体实现如下:

    //鼠标基类
    class Mouse{
        public void sayHi(){};
    }
    //鼠标扩展类
    class DellMouse extends Mouse{
        @Override
        public void sayHi() {
            System.out.println("产品:戴尔鼠标");
        }
    }
    class HpMouse extends Mouse{
        @Override
        public void sayHi() {
            System.out.println("产品:惠普鼠标");
        }
    }
    //鼠标工厂
    class MouseFactory{
        //生产鼠标的方法,所有的鼠标都通过该方法生成
        public static Mouse createMouse(int i) {
            switch (i) {
            case 0: return new DellMouse();
            case 1: return new HpMouse();
            default: return null;
            }
        }
    }
    public class NormFactory {
        public static void main(String[] args) {
            Mouse hpm = MouseFactory.createMouse(1);
            Mouse dellm = MouseFactory.createMouse(0);
            hpm.sayHi();
            dellm.sayHi();
        }
    }

    打印结果如下:

    产品:惠普鼠标
    产品:戴尔鼠标

    上述模式下,所有的鼠标都在同一个MouseFactory工厂下生产,有一个统一的create静态方法。在使用工厂时,不需要对工厂进行实例化,只需要调用该静态方法便可得到相应的产品。

    但如果用户需要添加新一类的产品,例如有一项华硕鼠标,工厂要生产该产品则需要改create函数,这有悖于设计原则的开闭原则。

    工厂模式

    在该模式下,不同品牌的产品交由不同的工厂来生产,有一个统一的工厂接口,生产该产品的工厂都要实现该接口。

    生产哪种产品不再由参数决定,而是在创建工厂时让工厂来决定,例如惠普的工厂只会生产惠普的鼠标,而戴尔的工厂只会生产戴尔的鼠标。

    具体实现如下:

    class Mouse{
        public void sayHi(){};
    }
    
    class DellMouse extends Mouse{
        @Override
        public void sayHi() {
            System.out.println("产品:戴尔鼠标");
        }
    }
    class HpMouse extends Mouse{
        @Override
        public void sayHi() {
            System.out.println("产品:惠普鼠标");
        }
    }
    //生产工厂接口
    interface MouseFactory{
        public Mouse createMouse();
    }
    //不同的鼠标交由不同的工厂生产
    class HpMouseFactory implements MouseFactory{
        @Override
        public Mouse createMouse() {
            return new HpMouse();
        }
    }
    class DellMouseFactory implements MouseFactory{
        @Override
        public Mouse createMouse() {
            return new DellMouse();
        }
    }
    public class NormFactory {
        public static void main(String[] args) {
            MouseFactory hpFact = new HpMouseFactory();
            MouseFactory dellFact = new DellMouseFactory();
            Mouse hpm = hpFact.createMouse();
            Mouse dellm = dellFact.createMouse();
            hpm.sayHi();
            dellm.sayHi();
        }
    }

    打印结果如下:

    产品:惠普鼠标
    产品:戴尔鼠标

    该模式下代码的可扩展性大大提高,当需要添加一种商品时,只需要添加生产该商品的工厂,并让其实现生产工厂接口即可。

    但在该模式下,商品的生产变得更为复杂,我们要得到一件商品,必须先得到一座生产该商品的工厂,再调用该工厂的生产方法才能得到该商品。

    抽象工厂模式

    该模式下的工厂生产的产品不唯一,同一品牌的工厂有着各种不同的产品,相当于是工厂模式的一个加强版。

    具体实现如下:

    class Mouse{
        public void sayHi(){};
    }
    
    class DellMouse extends Mouse {
        @Override
        public void sayHi() {
            System.out.println("产品:戴尔鼠标");
        }
    }
    class HpMouse extends Mouse {
        @Override
        public void sayHi() {
            System.out.println("产品:惠普鼠标");
        }
    }
    
    class KeyBoard {
        public void kick(){};
    }
    class HpKeyBoard extends KeyBoard {
        @Override
        public void kick() {
            System.out.println("产品:惠普键盘");
        }
    }
    class DellKeyBoard extends KeyBoard {
        @Override
        public void kick() {
            System.out.println("产品:戴尔键盘");
        }
    }
    //总的工厂接口
    interface PcFactory {
        public Mouse createMouse() ;
        public KeyBoard createKeyBoard() ;
    }
    class HpFactory implements PcFactory {
        @Override
        public Mouse createMouse() {
            return new HpMouse();
        }
    
        @Override
        public KeyBoard createKeyBoard() {
            return new HpKeyBoard();
        }
    }
    class DellFactory implements PcFactory {
        @Override
        public Mouse createMouse() {
            return new DellMouse();
        }
        @Override
        public KeyBoard createKeyBoard() {
            return new DellKeyBoard();
        }
    }
    
    //当需要增加一个华硕工厂时:
    class AsusMouse extends Mouse {
        @Override
        public void sayHi() {
            System.out.println("产品:华硕鼠标");
        }
    }
    class AsusKeyBoard extends KeyBoard {
        @Override
        public void kick() {
            System.out.println("产品:华硕键盘");
        }
    }
    class AsusFactory implements PcFactory {
        @Override
        public Mouse createMouse() {
            return new AsusMouse();
        }
        @Override
        public KeyBoard createKeyBoard() {
            return new AsusKeyBoard();
        }
    }
    
    public class NormFactory {
        public static void main(String[] args) {
            PcFactory hpFact = new HpFactory();
            Mouse hpm = hpFact.createMouse();
            KeyBoard hpkbd = hpFact.createKeyBoard();
            
            PcFactory dellFact = new DellFactory();
            Mouse dellm = dellFact.createMouse();
            KeyBoard dellkbd = dellFact.createKeyBoard();
            
            hpm.sayHi();
            dellm.sayHi();
            
            hpkbd.kick();
            dellkbd.kick();
        }
    }

    打印结果如下:

    产品:惠普鼠标
    产品:戴尔鼠标
    产品:惠普键盘
    产品:戴尔键盘

    但该模式如果要添加产品时,需要修改PcFactory、DellFactory、HpFactory等所有实现了PcFactroy接口的工厂类,这是十分不好的。

  • 相关阅读:
    start-stop-daemon 守护进程管理
    Proxmox VE 的安装和简单使用
    查询Linux下文件格式.
    re匹配 [sS][wW]的使用.
    prometheus简单监控Linux,mysql,nginx
    Linux中查看和修改分区的uuid方便挂载使用
    openssl 模块 安装 centso Ubuntu
    python写爬虫遇到需要解码js一些记录
    CSS 文字超出部分显示省略号
    新随笔
  • 原文地址:https://www.cnblogs.com/JuanF/p/9275833.html
Copyright © 2011-2022 走看看