zoukankan      html  css  js  c++  java
  • 设计模式之创建类模式大PK


    创建类模式大PK

    • 创建类模式包括工厂方法模式建造者模式抽象工厂模式单例模式原型模式,他们能够提供对象的创建和管理职责。其中单例模式和原型模式模式非常容易理解,单例模式是要保持在内存中只有一个对象,原型模式是通过复制的方式产生一个新的对象。而工厂方法模式、抽象工厂模式和建造者模式,这三者之间有较大的相似性。
    工厂方法模式VS建造者模式
    • 工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程,旨在通过一步一步地精确构造创建出一个复杂的对象。就拿造车来说吧,工厂方法模式,直接生产出来的就是奔驰、宝马和大众;而建造者模式则不同了,则需要创建车胎、引擎、车门、座椅、车灯等等,然后组装成一辆奔驰或者宝马车。如下我们分别介绍两种模式的造车过程。
    • 工厂方法模式造车

    首先工厂方法模式的类图如下,其中我们将车辆分为三种奔驰、宝马、大众,定义一个接口,在定义三种车型的创建实现,通过汽车制造工厂生产汽车。通过类图代码略。

    • 建造者模式造车

    建造者模式设计一个车需要先把车进行拆分,分为引擎、车轮和车体三部分,然后由建造者进行建造,并通过设计图纸建造车辆,注重零件的配合、组装和封装从一个细微构件角度看待一个对象,建造者模式的类图如下。

    这个看起来还有点复杂呢,我们还是看看通用类图的源码吧,一点一点的分析一下,首先我们还是先看看这个奔驰和宝马汽车吧,还是把大众汽车给忘记了!源码还是挺简单的,就是一些get和set方法。

    public interface ICar {
        public String getWheel();
        public String getEngine();
        public String getCarbody();
    }
    
    public class Benz implements ICar{
        private Blueprint bp;
        public Benz(Blueprint bp){
            this.bp = bp;
        }
        @Override
        public String getWheel() {
            // TODO Auto-generated method stub
            return this.bp.getWheel();
        }
    
        @Override
        public String getEngine() {
            // TODO Auto-generated method stub
            return this.bp.getEngine();
        }
    
        @Override
        public String getCarbody() {
            // TODO Auto-generated method stub
            return this.bp.getBody();
        }
    }
    
    public class BMW implements ICar{
        private Blueprint bp;
        public BMW(Blueprint bp){
            this.bp = bp;
        }
        public String getBody() {
            return this.bp.getBody();
        }
        public String getWheel() {
            // TODO Auto-generated method stub
            return this.bp.getWheel();
        }
        @Override
        public String getEngine() {
            // TODO Auto-generated method stub
            return this.bp.getEngine();
        }
        @Override
        public String getCarbody() {
            // TODO Auto-generated method stub
            return this.bp.getBody();
        }
    }
    View Code

    接下来我们看看我们重头戏CarBuilder,写起来发现也没有那么复杂了。

    public abstract class CarBuilder {
        private Blueprint bp;
        public abstract ICar buildCar();
        public void receiveBlueprint(Blueprint bp){
            this.bp = bp;
        }
        protected Blueprint getBlueprint(){
            return this.bp;
        }
    }
    
    public class BenzBuilder extends CarBuilder{
    
        @Override
        public ICar buildCar() {
            // TODO Auto-generated method stub
            return new Benz(super.getBlueprint());
        }
    }
    
    public class BMWBuilder extends CarBuilder{
    
        @Override
        public ICar buildCar() {
            // TODO Auto-generated method stub
            return new BMW(super.getBlueprint());
        }
    }
    View Code

    最后只剩下导演类了,看来最复杂的还是导演,要设计车辆的蓝图,并正确的调用建造方法。

    public class Director {
        private CarBuilder benzBuilder = new BenzBuilder();
        private CarBuilder BMWbuilder = new BMWBuilder();
        private Blueprint bp;
        public ICar createBenz(){
            bp = new Blueprint();
            bp.setBody("BenzBody");
            bp.setEngine("BenzEngine");
            bp.setWheel("BenzWheel");
            return createCar(benzBuilder, bp);
        }
        public ICar createBMW(){
            bp = new Blueprint();
            bp.setBody("BMWBody");
            bp.setEngine("BMWEngine");
            bp.setWheel("BMWWheel");
            return createCar(BMWbuilder, bp);
        }
        private ICar createCar(CarBuilder carBuilder, Blueprint bp){
            carBuilder.receiveBlueprint(bp);
            return carBuilder.buildCar();
        }
    }
    View Code

    大功告成,我们通过客户端调用一下看看运行状况。

    public class Client {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Director director = new Director();
            ICar benz = director.createBenz();
            ICar BMW = director.createBMW();
            System.out.println(benz.getCarbody());   //BenzBody
            System.out.println(BMW.getCarbody());    //BMWBody
        }
    }
    View Code
    • 最佳实践

     工厂方法模式和建造者模式都属于对象创建类模式,都是用来创建类对象。但他们之间区别还是比较明显的。

      • 意图不同:工厂方法模式关注的是产品的整体,如宝马、大众车整体,无需关心产品的各个部分是如何创建出来的;但在建造者模式中,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是“由零件一步一步地组装出产品对象”。工厂方法模式创建对象粒度较粗,而建造者模式创建对象的粒度较细。
      • 产品的复杂度不同,工厂方法模式创建出来的宝马和奔驰车的样子是一样的,而建造者模式创建的宝马车和奔驰车可以分别指定不同的车体部分。
    抽象工厂模式VS建造者模式

      抽象工厂模式实现对产品家族的创建,一个产品家族是一系列不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。我们生产的奔驰和宝马车当然不能各只有一种型号,奔驰车有商务车还有运动型车SUV,同样宝马车也是如此。因此我们需要改进工厂方法模式,引入抽象工厂模式生产车辆。抽象工厂模式类图如下:

      对外界调用者来说,只要更换了一个具备相同结构的对象,即可发生非常大的改变,如我们原本使用BenzFactory生产汽车,但是系统突然也生产宝马汽车,则只需要将BenzFactory替换为BMWFactory即可,注意这里生产的是一辆完整的车,对于一个产品,只要给出产品的代码即可生产,抽象工厂模式把一辆车认为是一个完整的,不可拆分的对象,注重完整性,不会出现一个宝马工厂生产奔驰车的情况,不能生产混合车型。而建造者模式可以将不同车型的零件任意组合。如果希望屏蔽对象的创建过程,只提供一个封装良好的对象,则可以选择抽象工厂模式。而建造者模式可以用在构件的装配方面,如通过装配不同的组件或者相同组件的不同顺序,可以产生出一个新的对象,是一个非常灵活的架构,方便地扩展和维护系统。

  • 相关阅读:
    Eclipse怎么汉化
    eclipse的 project explore找不到了, 怎么把复制来的包放在project explore
    三 地图的绘制
    二 CheatEngine怎么提取地图数据
    一. 透明坦克跑起来
    第七章 继承与派生
    Quoit Design HDU
    C++学习_从C到C++
    C++学习_一道程序填空题重拾C++
    网络爬虫_BeautifulSoup库入门
  • 原文地址:https://www.cnblogs.com/zhanglei93/p/6138445.html
Copyright © 2011-2022 走看看