精华内容
下载资源
问答
  • 文章目录设计模式GoF设计模式简要说明创建型模式简单工厂模式工厂方法模式应用实例模式优缺点适用场景抽象工厂模式模式优缺点结构型模式行为型模式 设计模式 设计模式是在特定环境下为解决某一通用软件设计问题...

    设计模式

    设计模式是在特定环境下为解决某一通用软件设计问题提供的一套定制的解决方案,该方案描述了对象与类之间的相互作用

    GoF设计模式

       在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。

    四位作者合称 GOF(四人帮,全拼 Gang of Four)。他们所提出的设计模式主要是基于以下的面向对象设计原则。

    • 对接口编程而不是对实现编程。
    • 优先使用对象组合而不是继承。

    根据目的(模式是用来做什么的)可分为创建型(Creational),结构型(Structural),行为型(Behavioral)

    范围 / 目的 创建型5 结构型7 行为型11
    类模式 工厂方法模式 (类)适配器模式 解释器模式
    模板方法模式
    对象模式 抽象工厂模式
    建造方法模式
    原型模式
    单例模式
    (对象)适配器模式
    桥接模式
    组合模式
    装饰者模式
    外观模式
    享元模式
    代理模式
    职责模式
    命令模式
    迭代器模式
    中介者模式
    备忘录模式
    观察者模式
    状态模式
    策略模式
    访问者模式

    简要说明

    模式类别 模式名称 模式说明 补充 角色
    创建型模式(Creational) 工厂方法模式 定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工程方法模式让一个类的实例化延迟到其子类 工厂方式模式提供一个抽象工厂接口来声明工厂方法,然后由其子类工厂类来实现工厂方法,创建具体的产品对象 1.抽象产品 2.具体产品 3.抽象工厂 4.具体工厂
    抽象工厂模式 提供一个创建一系列类相关或相互依赖对象的接口,而无需指定它们具体的类 相对于类创建模式->工厂方法模式,对象创建模式抽象工厂模式提供的工厂类创建的具体对象并不简单是一个简单的对象,分成多种类型,处于同一个工厂类的产品形成产品系列。 1.抽象工厂 2.具体工厂 3.抽象产品 4.具体产品
    建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 建造者模式提供了一个抽象建造者来声明抽象的buildPartX()方法,具体建造过程在具体建造者中实现,此外还提供工厂方法getResult返回产品对象。通过注入产品对象的指挥者类完成产品的构建和组装。 1.抽象建造者 2.具体建造者 3.产品 4.指挥者
    原型模式 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象 原型模式提供了一个抽象原型声明clone方法,返回类型为待创建产品类型的超类,具体原型实现clone方法,根据原型实例进行复制本身,返回新创建的对象 1.抽象原型 2.具体原型 3.客户
    单例模式 确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例
    结构型模式(Structural) 适配器模式 将一个类的接口转化成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作
    桥接模式 抽象部分和它的实现部分解耦,使得两者可以独立变化
    组合模式 组合多对个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象
    装饰模式 动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案 动态增强
    外观模式 为子系统中的一组接口提供一个统一的入口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
    享元模式 运用共享技术有效地支持大量细粒度对象的复用
    代理模式 给某一对象提供一个代理或占位符,并由代理对象来控制对原对象的访问
    行为型模式(Behavioral) 职责链模式 避免将一个请求的发送者与接受者耦合在一起,让多个对象都有机会处理请求。将接受请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止
    命令模式 将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销车操作
    解释器模式 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
    迭代器模式 提供一种方法顺序访问一个聚合对象中的各个元素,而又不用暴露该对象的内部表示
    中介者模式 定义一个对象来封装一系列对象的交互。中介者模式使个对象之间不需要显示地互相吸引,从而使其耦合松散,而且可以独立地改变它们之间的交互
    备忘录模式 不破坏封装的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原有保存的状态
    观察者模式 定义对象对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时其相关依赖对象都得到通知并被自动更新
    状态模式 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
    策略模式 定义一系列算法,将每一个算法封装其来,并让它们可以相互替换。策略模式让算法可以独立于使用它的客户而变化
    模板方法模式 定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
    访问者模式 表示一个作用于某对象结构中的各个元素的操作。访问者模式可以在不改变各元素的类的前提下定义作用于这些元素的新操作

    1.创建型模式

    1.1.0简单工厂模式

    该模式不属于GoF的23种经典设计模式,但可作为学习其他工厂模式的基础

    定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有公共的父类

    由于在简单工厂模式中创建实例的方法通常是静态方法,因此简单工厂模式又被称为静态工程模式,它是一种类创建型模式。

    模式结构

    1. Factory工厂角色: 工厂类,提供静态的工厂方法factoryMethod(),返回类型为抽象产品类型Product
    2. Product抽象产品角色: 它是所有工厂类创建的所有对象的父类(或接口),封装了各种产品对象的共有方法(子类继承父类的公有方法)。提供系统的灵活性,使得工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象(或实现类对象)
    3. ConcreteProduct具体产品角色: 它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法

    示例

    package com.dust.DesignPatterns.Creational.SimpleFactory;
    
    /**
     * @author dustdawn
     * @date 2019/10/31 16:02
     */
    public abstract class Product {
        //所有产品类的公共业务方法
        public void methodSame() {
    
        }
        //声明抽象业务方法
        public abstract void methodDiff();
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.SimpleFactory;
    
    /**
     * @author dustdawn
     * @date 2019/10/31 16:07
     */
    public class ConcreteProductA extends Product {
        @Override
        public void methodDiff() {
            //A业务方法
        }
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.SimpleFactory;
    
    /**
     * @author dustdawn
     * @date 2019/10/31 16:08
     */
    public class ConcreteProductB extends Product {
        @Override
        public void methodDiff() {
            //B业务方法
        }
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.SimpleFactory;
    
    /**
     * @author dustdawn
     * @date 2019/10/31 16:04
     */
    public class Factory {
        //静态工程方法
        public static Product getProduct(String arg) {
            Product product = null;
            //忽略大小写
            if (arg.equalsIgnoreCase("A")) {
                product = new ConcreteProductA();
            }else if (arg.equalsIgnoreCase("B")) {
                product = new ConcreteProductB();
            }
            return product;
        }
    
        public static void main(String[] args) {
            Product product;
            product = Factory.getProduct("A");
            product.methodSame();
            product.methodDiff();
        }
    }
    
    
    

    1.1工厂方法模式

    简单工厂模式再增加新类型具体对象时,要修改工厂类的代码,一定程度上违反了开放封闭原则。而工厂方法模式将具体对象的创建过程交给了专门的工厂子类去实现。

    定义一个抽象的工厂类,再定义具体的工厂类

    工厂方式模式提供一个抽象工厂接口来声明工厂方法,然后由其子类工厂类来实现工厂方法,创建具体的产品对象

    定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工程方法模式让一个类的实例化延迟到其子类

    模式结构

    1. Product抽象产品角色: 定义产品的接口,是工厂方法模式所创建对象的父类型
    2. ConcreteProduct具体产品角色: 实现了抽象产品接口,某种类型的具体产品由具体工厂创建,具体工厂与具体产品一一对应
    3. Factory抽象工厂角色: 抽象工厂类,声明了工厂方法factoryMethod(),返回类型为抽象产品类型Product,所有创建对象的具体工厂类都必须实现该接口
    4. ConcreteFactory具体工厂角色: 是抽象工厂类的子类或实现类,实现了在抽象工厂中声明的工厂方法,返回一个具体产品类的实例

    示例

    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    import com.dust.DesignPatterns.Creational.SimpleFactory.Product;
    
    /**
     * @author dustdawn
     * @date 2019/10/31 16:22
     */
    public interface Factory {
        //抽象工厂,可以是接口,也可以是抽象类或者具体类
        public Product factoryMethod();
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    import com.dust.DesignPatterns.Creational.SimpleFactory.ConcreteProductA;
    import com.dust.DesignPatterns.Creational.SimpleFactory.Product;
    
    /**
     * @author dustdawn
     * @date 2019/10/31 16:24
     */
    public class ConcreteFactoryA implements Factory{
        @Override
        public Product factoryMethod() {
            return new ConcreteProductA();
        }
    }
    
    

       在实际使用时,具体工厂类在实现工厂方法时,除了创建具体产品对象以外,还可以负责产品对象的初始化工作以及一些资源和环境配置工作,例如连接数据库,创建文件等

    应用实例

    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 14:50
     */
    
    /**
     * 日志记录器接口,充当抽象产品角色
     */
    public interface Logger {
        public void writeLog();
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 14:51
     */
    
    /**
     * 文件日志记录器,充当具体产品角色
     */
    public class FileLogger implements Logger{
        @Override
        public void writeLog() {
            System.out.println("文件日志记录");
        }
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 14:50
     */
    
    /**
     * 数据库日志记录器,充当具体产品角色
     */
    public class DatabaseLogger implements Logger{
        @Override
        public void writeLog() {
            System.out.println("数据库日志记录");
        }
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 14:51
     */
    
    /**
     * 日志记录器工厂接口,充当抽象工厂角色
     */
    public interface LoggerFactory {
        //抽象工厂方法
        public Logger createLogger();
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 14:53
     */
    
    /**
     * 文件日志记录器工厂类,充当具体工厂角色
     */
    public class FileLoggerFactory implements LoggerFactory{
        @Override
        public Logger createLogger() {
            //创建文件日志记录器对象
            FileLogger fileLogger = new FileLogger();
            //创建文件,代码省略
            return fileLogger;
        }
    }
    //=====================================================================================
    package com.dust.DesignPatterns.Creational.FactoryMethod;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 14:52
     */
    
    /**
     * 数据库日志记录器工厂类,充当具体工厂角色
     */
    public class DatabaseLoggerFactory implements LoggerFactory{
        @Override
        public Logger createLogger() {
            //连接数据库
            //创建数据库日志记录器对象
            DatabaseLogger databaseLogger = new DatabaseLogger();
            //初始化数据库日志记录器,代码省略
            return databaseLogger;
        }
    }
    //=====================================================================================
    

    模式优缺点

    优点:

    • 向客户隐藏了哪一种具体产品类将被实例化这一细节,用户只需关心所需产品对应的工厂,无需关心创建细节
    • 将创建具体对象的细节完全封装在具体工厂内部,基于工厂角色和产品角色的多态性设计,所有的具体工厂类都具有同一抽象父类
    • 系统加入产品时,无需修改抽象工厂和抽象产品提供的接口,也无需修改其他的具体工厂和具体产品,子类之间不形成耦合,只需要提供有一个具体工厂和具体产品即可。可扩展性好,完全符合开放封闭原则。

    缺点:

    • 添加新产品时,成对增加系统中类的个数,一定程度增加了系统的复杂度,更多的编译和运行给系统带来一些额外的开销
    • 由于考虑到系统的可扩展性,需要引入抽象层,增加了系统的抽象性和理解程度

    适用场景

    • 当用户需要一个类的子类实例,并且不希望与该类的子类形成耦合或者不知道该类有哪些子类可用时,可采用工厂方法模式
    • 不需要知道具体产品的类名,只需要知道锁对应的工厂即可,具体产品对象由具体工厂类创建,可将具体工厂类的类名存储在配置文件或数据库中
    • 抽象工厂通过其子类来指定创建哪个对象。对于抽象工厂类,只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象。利用面向对象和多态性和里氏替换原则,在程序运行时子类对象将覆盖父类对象,从而使得系统容易扩展

    1.2抽象工厂模式

    当系统所提供的的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时就可以使用抽象工厂结构。

    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

    又称工具Kit模式,对象创建型模式

    模式结构

    1. AbstractFactory抽象工厂角色: 声明创建一组用于创建一个产品系列的方法(系列1,系列2…),每一个工厂方法对应一种产品(A,B,C,D…)
    2. ConcreteFactory具体工厂角色: 实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个系列的产品
    3. AbstractProduct抽象产品角色: 为每种产品(A,B,C…)声明接口,在抽象产品中声明了产品具有的业务方法
    4. ConcreteProduct具体产品角色: 定义具体工厂生成的具体产品对象,实现抽象产品接口中声明的业务方法

    应用实例

    在抽象工厂中声明多个工厂方法,用于创建不同类型的产品(A,B,C…),抽象工厂可以是接口,也可以是抽象类或具体类

    package com.dustdawn.DesignPatterns.Creational.AbstractFactory;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 16:10
     */
    
    /**
     * 抽象工厂方法角色
     */
    public interface AbstractFactory {
        public AbstractProdustA createProductA();//工厂方法一
        public AbstractProdustB createProductB();//工厂方法二
    }
    

    具体工厂实现了抽象工厂,对每一个具体的工厂方法可以返回一个特定的产品对象。同一个具体工厂所创建的产品对象构成了一个产品对象构成一个产品系列。

    package com.dustdawn.DesignPatterns.Creational.AbstractFactory;
    
    /**
     * @author dustdawn
     * @date 2019/11/2 16:15
     */
    
    /**
     * 具体工厂角色1
     */
    public class ConcreteFactory1 implements AbstractFactory{
        @Override
        public AbstractProdustA createProductA() {
            return new ConcreteProductA1();
        }
    
        @Override
        public AbstractProdustB createProductB() {
            return new ConcreteProductB1();
        }
    }
    //...
    

    模式优缺点

    优点:

    • 隔离了具体类的生成,使得客户端并不需要直到谁被创建。由于这种隔离,更换一个具体工厂容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,只需要改变具体工厂的实例即可在某种程度下改变整个软件系统的行为。
    • 当一个产品系列的多个对象设计成一起工作时,它能够保证客户端始终只使用同一个产品系列中的对象
    • 增加新的产品系列很容易,无需修改已有系统,符合开放封闭原则

    缺点:

    • 增加产品类型复杂,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背了开放封闭原则

    适用场景

    • 不依赖于产品类实例如何被创建,组合,表达的细节,无需关心对象的创建过程,将对象的创建和使用解耦
    • 系统中有多于一个的产品系列,而每次只能使用其中某一类型产品,可以通过配置文件等方式来使用户能够动态改变和增加产品系列
    • 属于同一种产品系列的产品将在一起被使用,这一约束必须在系统的设计中体现出来
    • 产品等级结构稳定

    1.3建造者模式

    建造者模式是一种对象创建模式,将包含多个部件的复杂对象的创建过程分离,关注如何一步一步创建一个复杂的对象,不同的建造者定义了不同的创建过程

    将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

    模式结构

    1. Builder抽象建造者: 它为创建一个产品对象的各个部件指定抽象接口,该接口中一般声明两类方法:一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类是getResult(),它们用于返回复杂对象。Build既可以是抽象类,也可以是接口。
    2. ConcreteBuild具体建造者: 实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确所常见的复杂对象,还可以提供一个方法返回创建好的复杂产品对象(也可以在抽象建造者中提供)
    3. Product产品角色: 被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示,并定义它的装配过程
    4. Director指挥者角色: 负责安排复杂对象的建造次序,可以在其construct()建造方法中调用建造者对象的部件构造和装配方法完成对复杂对象的建造。用户与指挥者交互,确定具体建造者的类型,并实例化其对象。然后通过指挥者类的构造方法或者Setter方法将该对象传入指挥者类中

    应用实例

    package com.dustdawn.DesignPatterns.Creational.BuilderPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 10:10
     */
    
    /**
     * 复杂产品角色
     */
    public class Product {
        private String partA;//部件
        private String partB;
        private String partC;
    
        //Getter和Setter方法
    }
    //=====================================================================================
    

    在建造者类中定义了产品的创建和返回方法

    package com.dustdawn.DesignPatterns.Creational.BuilderPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 13:39
     */
    
    /**
     * 抽象建造者类
     */
    public abstract class Builder {
        //创建产品对象
        protected Product product = new Product();
    
        public abstract void buildPartA();
        public abstract void buildPartB();
        public abstract void buildPartC();
    
        //返回产品角色
        public Product getResult() {
            return product;
        }
    }
    

    具体建造者类实现抽象的建造方法

    package com.dustdawn.DesignPatterns.Creational.BuilderPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 13:42
     */
    
    /**
     * 具体建造类
     */
    public class ConcreteBuilder1 extends Builder{
    
        @Override
        public void buildPartA() {
            super.product.setPartA("A1");
        }
    
        @Override
        public void buildPartB() {
            super.product.setPartB("B1");
        }
    
        @Override
        public void buildPartC() {
            super.product.setPartC("C1");
        }
    }
    

    指挥者类Director作用:

    • 隔离用户和创建过程
    • 控制产品对象的创建过程,包括某个buildPartX()方法是否被调用以及多个方法的调用顺序

    指挥者类可以注入一个抽象建造者类型的对象,它提供一个建造方法construct(),在该方法中调用了builder对象的构造部件的方法(利用多态特性由具体建造者对象实现),最后返回一个产品类型

    package com.dustdawn.DesignPatterns.Creational.BuilderPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 15:52
     */
    public class Client {
        public static void main(String[] args) {
            ConcreteBuilder1 concreteBuilder1 = new ConcreteBuilder1();
            Director director = new Director(concreteBuilder1);
            Product product = director.construct();
    
        }
    }
    

    省略指挥者类,可将建造方法定义在抽象建造者中,如静态方法,通过静态方法完成建造过程,或成员方法,通过内部定义成员product和成员方法达到相同效果

    钩子方法Hook Method

    建造者模式除了逐步构建一个复杂产品对象外,还可以通过Director类更加精细地控制产品的创建过程。

    可通过一类特殊方法钩子方法来控制是否对某个buildPartX()进行调用

    public boolean isBareheaded() {return false;}
    

    抽象建造者类设置为false,具体建造者类设置为false重写方法

    模式优缺点

    优点:

    • 用户不必知道产品内部组成的细节,将产品本身和产品的创建过程解耦,使得相同的创建过程能创建出不同的产品对象
    • 每一个具体建造者都相对独立,方便替换。由于指挥者类针对抽象建造者编程,增加新的具体建造者类无需修改原有代码,系统扩展方便,符合开放封闭原则
    • 更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,方便管理

    缺点:

    • 要求产品之间具有较多共同点(如设计不同游戏角色的模型自定义),产品之间差异性很大或很大组成部分不相同则不适合建造者模式
    • 如果产品内部变化复杂,可能会导致需要许多具体建造者来实现,导致系统庞大,增加系统理解程度和运行成本

    适用场景

    • 需要生成的产品对象有复杂的内部结构,这些产品对象通常包括多个成员变量
    • 需要生成的产品对象的属性相互依赖,需要指定其生成顺序
    • 对象的创建过程独立于创建该对象的类。在建造者模式中通过指挥者类将创建过程封装在指挥者类中,而不在建造者类或用户类中
    • 隔离复杂对象的创建和使用,并使相同的创建过程能创建出不同的产品

    1.4原型模式

    原型模式是一种对象创建型模式,将一个原型对象传给要发动创建的对象(即客户端对象),这个要发动创建的对象通过请求原型复制自己来实现创建过程。

    使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

    模式结构

    1. Prototype抽象原型类: 声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类,也可以是接口,甚至可以是具体实现类
    2. ConcretePrototype具体原型类: 实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象
    3. Client类: 在客户类中,让一个原型对象克隆自身从而创建一个新的对象,只需要直接实例化或者通过工厂方法等方式创建一个原型对象,再通过该对象的克隆方法即可得到多个相同的对象。由于客户端针对抽象原型类Prototype编程,因此客户可以根据需要选择具体原型类,系统具有较好的扩展性,增加更换具体原型类都很方便。

    根据复制原型对象的同时是否复制包含在原型对象中引用类型的成员变量,分为浅克隆(Shallow Clone)和深克隆(Deep Clone)

    应用实例

    1. 通用实现
    package com.dustdawn.DesignPatterns.Creational.PrototypePattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 15:56
     */
    
    /**
     * 抽象原型类
     */
    public abstract class Prototype {
        public abstract Prototype clone();
    }
    //=====================================================================================
    
    package com.dustdawn.DesignPatterns.Creational.PrototypePattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 15:58
     */
    
    /**
     * 具体原型类
     */
    public class ConcretePrototype extends Prototype{
        private String str;//成员变量
    
        public String getStr() {
            return str;
        }
    
        public void setStr(String str) {
            this.str = str;
        }
    
    
        @Override
        public Prototype clone() {
            Prototype prototype = new ConcretePrototype();
            ((ConcretePrototype) prototype).setStr(this.str);
            return prototype;
        }
        
    }
    //=====================================================================================
    
    1. Java中Clone方法和Cloneable接口(标识性接口,表示Java类支持被复制)

      将Object类充当抽象原型类,ConcretePrototypeII充当具体原型类,Prototype充当成员类,实现对原型对象的复制(浅拷贝)

    package com.dustdawn.DesignPatterns.Creational.PrototypePattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/4 16:04
     */
    public class ConcretePrototypeII implements Cloneable{
        public Prototype clone() {
            Object object = null;
            try {
                object = super.clone();
            }catch (CloneNotSupportedException e) {
                System.err.println("Not support cloneable");
            }
            return (Prototype) object;
        }
    }
    
    

    模式优缺点

    优点:

    • 简化对象的创建过程,通过赋值一个已有实例可以提高新实例的创建效率
    • 扩展性较好,针对抽象原型类进行编程,可将具体编程类写在配置文件中
    • 提供简化的创建结构,通过封装在原型类中的克隆方法实现,无需专门的工厂类来创建产品
    • 可以使用深克隆保存对象的状态,待需要时恢复,可辅助实现撤销操作

    缺点:

    • 需要为每一个类配备一个克隆方法,改造时需要修改源代码,违背了开放封闭原则
    • 实现深克隆时需要编写较为复杂的代码,当对象之间存在多重的嵌套引用时,每一层对象都必须支持深克隆

    适用场景

    • 创建新对象成本比较大,新对象可以通过赋值已有对象来获得,如果相相似对象对其成员变量可以稍做修改
    • 系统要保存对象的状态,而对象的状态变化很小
    • 需要避免使用分层次的工厂类来创建分层次的对象,以及避免类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例比较方便

    1.5单例模式

    保证一个类的实例只有一个并且这个实例易于访问

    确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例

    模式结构

    1. 一个单例角色,单例类Singleton
    2. 内部创建唯一实例,并通过静态方法getInstance()让客户端可以使用它的唯一实例
    3. 防止外部对单例类实例化,将其构造函数的可见性设为private
    4. 在单例类内部定义了一个Singleton类型的静态对象作为供外部访问的唯一实例

    实例

    package com.dustdawn.DesignPatterns.Creational.SingletonPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/5 14:42
     */
    
    /**
     * 懒汉式单例模式
     * 线程安全,第一次调用初始化,避免资源浪费,
     * 但必须加锁才能保证单例,加锁影响效率
     */
    public class SingletonI {
        private static SingletonI instance = null;//静态私有成员变量
        //私有构造函数
        private SingletonI() {}
        //静态共有工厂方法,返回唯一实例
        //保证线程安全
        public static synchronized SingletonI getInstance() {
            if (null == instance) {
                instance = new SingletonI();
            }
            return instance;
        }
    }
    //=====================================================================================
    package com.dustdawn.DesignPatterns.Creational.SingletonPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/5 14:48
     */
    
    /**
     * 饿汉式单例模式
     * 没有加锁,但浪费资源,执行效率高
     */
    public class SingletonII {
        private static SingletonII instance = new SingletonII();//静态私有成员变量
        //私有构造函数
        private SingletonII() {}
        //静态共有工厂方法,返回唯一实例
        public static synchronized SingletonII getInstance() {
            return instance;
        }
    }
    
    //=====================================================================================
    package com.dustdawn.DesignPatterns.Creational.SingletonPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/5 14:51
     */
    
    /**
     * 静态内部类实现单例模式(登记类)
     */
    public class SingletonIII {
        //通过静态内部类初始化的静态成员返回单例
        private static class SingletonHandler{
            private  static SingletonIII instance = new SingletonIII();
        }
    
        private SingletonIII(){}
        //在调用getInstance方法才初始化静态类
        public static SingletonIII getInstance() {
            return SingletonHandler.instance;
        }
    }
    
    //=====================================================================================
    package com.dustdawn.DesignPatterns.Creational.SingletonPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/5 14:54
     */
    
    /**
     * 双重校验锁DCL的线程安全的单例模式
     */
    public class Singleton {
        //volatile保证线程之间可见性和屏蔽JVM重排序
        //也会屏蔽一些JVM的代码优化导致运行效率低,所有也不完美
        private volatile static Singleton instance = null;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            //第一个if在已创建实例后直接返回实例,不再进入同步代码块竞争锁
            if (null != instance) {
                synchronized(Singleton.class) {
                    //第二个if防止同时通过第一个if的多个线程创建多个实例
                    if (null != instance) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    应用实例

    package com.dustdawn.DesignPatterns.Creational.SingletonPattern;
    
    /**
     * @author dustdawn
     * @date 2019/11/5 15:03
     */
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    /**
     * 场景:
     *  通过一个负载均衡器负责服务器的管理和请求的分支
     */
    public class LoadBalancer {
        //负载均衡器单例角色
        private static LoadBalancer instance = null;
        //服务器集合角色
        private List serverList = null;
        //私有构造函数对服务器集合进行初始化
        private LoadBalancer() {
            serverList = new ArrayList();
        }
    
        public static LoadBalancer getLoadBalancer() {
            if (null != instance) {
                instance = new LoadBalancer();
            }
            return instance;
        }
        //增加服务器
        public void addServer(String server) {
            serverList.add(server);
        }
        //移除服务器
        public void removeServer(String server) {
            serverList.remove(server);
        }
        //获得服务器
        public String getServer() {
            Random random = new Random();
            int i = random.nextInt(serverList.size());
            return (String) serverList.get(i);
        }
    
    }
    

    模式优缺点

    优点:

    • 提供了对唯一实例的受控访问
    • 由于在系统内存只有一个对象,所有可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能
    • 允许可变数目的实例

    缺点:

    • 没有抽象层,扩展困难
    • 单例类的职责过重,一定程度违反了单一职责原则。既提供了业务方法,又提供了创建对象的方法,将对象的创建和对象本身的功能耦合在一起
    • 垃圾回收器可能会自动销毁并回收长时间不被使用的实例对象,这会导致共享的单例对象状态的丢失

    适用场景

    • 系统只需要一个实例对象,或因为资源消耗太大而只允许创建一个对象
    • 对单个实例只允许使用一个公共访问点,不可通过其他途径
    • 频繁创建和销毁的对象的情形。如数据库连接池,读取配置的类,日志应用等。
    展开全文
  • 第3集 创建型设计模式-建造者模式应用介绍《上》 第4集 创建型设计模式-建造者模式应用介绍《下》 干货文档 第1集 创建型设计模式-Prototype原型设计模式实战《上》 简介:讲解原型设计模式介绍和应用场景...

    logo 愿景:"让编程不再难学,让技术与生活更加有趣"


    更多架构课程请访问 xdclass.net

    目录

    第1集 创建型设计模式-Prototype原型设计模式实战《上》

    第2集 创建型设计模式-Prototype原型设计模式实战《下》

    第3集 创建型设计模式-建造者模式应用介绍《上》

    第4集 创建型设计模式-建造者模式应用介绍《下》

    干货文档


     

     

    第1集 创建型设计模式-Prototype原型设计模式实战《上》

    简介:讲解原型设计模式介绍和应用场景《上》

    • 原型设计模式Prototype

      • 是一种对象创建型模式,使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象,主要用于创建重复的对象,同时又能保证性能
      • 工作原理是将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝自己来实现创建过程
      • 应该是最简单的设计模式了,实现一个接口,重写一个方法即完成了原型模式

     

    • 核心组成

      • Prototype: 声明克隆方法的接口,是所有具体原型类的公共父类,Cloneable接口
      • ConcretePrototype : 具体原型类
      • Client: 让一个原型对象克隆自身从而创建一个新的对象

     

    • 应用场景

      • 创建新对象成本较大,新的对象可以通过原型模式对已有对象进行复制来获得
      • 如果系统要保存对象的状态,做备份使用

     

     

     

     

     

     

     

     

     

    第2集 创建型设计模式-Prototype原型设计模式实战《下》

    简介:讲解原型设计模式介绍和应用场景《下》

    • 遗留问题:

      • 通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的

      • 浅拷贝实现 Cloneable,深拷贝是通过实现 Serializable 读取二进制流

      • 拓展

        • 浅拷贝
        
        
        
        如果原型对象的成员变量是基本数据类型(int、double、byte、boolean、char等),将复制一份给克隆对象;
        如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址
        ​
        通过覆盖Object类的clone()方法可以实现浅克隆
        • 深拷贝
        
         

         

        
         
        无论原型对象的成员变量是基本数据类型还是引用类型,都将复制一份给克隆对象,如果需要实现深克隆,可以通过序列化(Serializable)等方式来实现
        • 原型模式是内存二进制流的拷贝,比new对象性能高很多,使用的时候记得注意是选择浅拷贝还是深拷贝
    • 优点

      • 当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,可以提高新实例的创建效率
      • 可辅助实现撤销操作,使用深克隆的方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用恢复到历史状态

     

    • 缺点

      • 需要为每一个类配备一个克隆方法,对已有的类进行改造时,需要修改源代码,违背了“开闭原则”
      • 在实现深克隆时需要编写较为复杂的代码,且当对象之间存在多重的嵌套引用时,需要对每一层对象对应的类都必须支持深克隆
    
     
    
    
    public class Person implements Cloneable, Serializable {
    ​
        private String name;
    ​
        private int age;
    ​
        private List<String> list = new ArrayList<>();
    ​
    ​
        public List<String> getList() {
            return list;
        }
    ​
        public void setList(List<String> list) {
            this.list = list;
        }
    ​
        public Person() {
            System.out.println("构造函数调用");
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public int getAge() {
            return age;
        }
    ​
        public void setAge(int age) {
            this.age = age;
        }
    ​
        @Override
        protected Person clone() throws CloneNotSupportedException {
            return (Person) super.clone();
        }
    ​
        /**
         * 深拷贝
         * @return
         */
        public Object deepClone() {
    ​
            try {
                //输出 序列化
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(this);
    ​
                //输入 反序列化
                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bais);
                Person copyObj = (Person) ois.readObject();
    ​
                return copyObj;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    ​
    }
    
    
    
    
    
    
    
    
    

     

    第3集 创建型设计模式-建造者模式应用介绍《上》

    简介:讲解建造者模式介绍和应用场景《上》

    • 建造者模式(Builder Pattern)

      • 使用多个简单的对象一步一步构建成一个复杂的对象,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

      • 允许用户只通过指定复杂对象的类型和内容就可以构建它们,不需要知道内部的具体构建细节

         

    • 场景举例

      • KFC创建套餐:套餐是一个复杂对象,它一般包含主食如汉堡、烤翅等和饮料 如果汁、 可乐等组成部分,不同的套餐有不同的组合,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐

      timg

      • 电脑有低配、高配,组装需要CPU、内存、电源、硬盘、主板等

        image-20200927120601344

    • 核心组成

      • Builder:抽象建造者,定义多个通用方法和构建方法
      • ConcreteBuilder:具体建造者,可以有多个
      • Director:指挥者,控制整个组合过程,将需求交给建造者,由建造者去创建对象
      • Product:产品角色

     

     

     

     

     

     

     

     

     

     

    第4集 创建型设计模式-建造者模式应用介绍《下》

    简介:讲解建造者模式介绍和应用场景《下》

    • 编码实践(同个设计模式 包括博文、书籍等不会完全相同,大体思想一致就行)
    
    
    
    /**
     * 声明了建造者的公共方法
     */
    public interface Builder {
    ​
        /**
         *细节方法
         */
        void buildCpu();
    ​
        void buildMainboard();
    ​
        void buildDisk();
    ​
        void buildPower();
    ​
        void buildMemory();
    ​
        Computer createComputer();
    ​
    }
    ​
    ​
    /**
     * 小滴课堂,愿景:让技术不再难学
     *
     * @Description 将产品和创建过程进行解耦,使用相同的创建过程创建不同的产品,控制产品生产过程
     *               Director是全程指导组装过程,具体的细节还是builder去操作
     * @Author 二当家小D
     * @Remark 有问题直接联系我,源码-笔记-技术交流群 微信:  xdclass6
     * @Version 1.0
     **/
    ​
    public class Director {
    ​
        public Computer craete(Builder builder){
    ​
            builder.buildMemory();
            builder.buildCpu();
            builder.buildMainboard();
            builder.buildDisk();
            builder.buildPower();
    ​
            return builder.createComputer();
    ​
        }
    ​
    }
    ​
    ​
    ​
    ​
    public class HighComputerBuilder implements Builder{
    ​
        private Computer computer = new Computer();
    ​
        @Override
        public void buildCpu() {
            computer.setCpu("高配 CPU");
        }
    ​
        @Override
        public void buildMainboard() {
            computer.setMainboard("高配 主板");
        }
    ​
        @Override
        public void buildDisk() {
            computer.setDisk("高配 磁盘");
        }
    ​
        @Override
        public void buildPower() {
            computer.setPower("高配 电源");
        }
    ​
        @Override
        public void buildMemory() {
            computer.setMemory("高配 内存");
        }
    ​
        @Override
        public Computer createComputer() {
            return computer;
        }
    }
    ​

     

    • 优点

      • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦
      • 每一个具体建造者都相对独立,而与其他的具体建造者无关,更加精细地控制产品的创建过程
      • 增加新的具体建造者无须修改原有类库的代码,符合开闭原则
      • 建造者模式结合链式编程来使用,代码上更加美观
    • 缺点

      • 建造者模式所创建的产品一般具有较多的共同点,如果产品差异大则不建议使用

       

    • JDK里面的应用

      • tcp传输协议 protobuf 生成的api、java中的StringBuilder(不完全一样,思想一样)

       

    • 建造者模式与抽象工厂模式的比较:

      • 建造者模式返回一个组装好的完整产品 , 抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族

     

     

    干货文档

    展开全文
  • 结合实例,正确无误地绘制组合模式、外观模式的模式结构图; 要求能使用XML和Java反射机制来创建对象。 使用Java语言实现组合模式、外观模式实例,代码运行正确无误。 二、实现过程及步骤 1.某教育机构组织结构如...

    一、题目要求

    1. 结合实例,正确无误地绘制组合模式、外观模式的模式结构图;
    2. 要求能使用XML和Java反射机制来创建对象。
    3. 使用Java语言实现组合模式、外观模式实例,代码运行正确无误。

    二、实现过程及步骤

    1.某教育机构组织结构如下图所示:
    在这里插入图片描述
    在该教育机构的OA系统中可以给各级办公室下发公文,试采用组合模式设计该机构的组织结构,绘制相应的类图并编程模拟实现,在客户端代码中模拟下发公文。

    (1)组合模式设计:

    组合模式是将对象组合成树形结构以表示“部分-整体”的层次结构。首先设计一个AbstractBranch类,用于访问和管理子部件,里面有两个抽象方法ReceiveDoc()和getName(),然后设计两个子类AdOffice,EdOffice去实现父类的方法,其次再设计一个有枝结点类Branch继承AbstractBranch类,里面不但包含实现父类的方法,而且有增加和删除结点的add()和remove()方法。最后设计一个XMLUilt类去获取.xml配置文件中的具体类名并返回一个实例对象。

    (2)UML类图如下:
    在这里插入图片描述
    (3)运行结果如下:
    在这里插入图片描述
    (4)主要代码如下:
    AbstractBranch类

    package compositepattern;
    
    public abstract class AbstractBranch {
    
    	public abstract void receiveDoc();
    	public abstract String getName();
    	public void setName(String name) {}
    }
    

    子类AdOffice,EdOffice

    package compositepattern;
    
    public class AdOffice extends AbstractBranch{
    
    	private String name;
    	public void receiveDoc() {
    		System.out.println("行政办公室收到文件");
    	}
    	
    	public AdOffice(String name) {
    		this.name = name;
    	}
    	
    	public String getName() {
    		return name;
    	}
    }
    
    package compositepattern;
    
    public class EdOffice extends AbstractBranch{
    
    	private String name;
    	public void receiveDoc() {
    		System.out.println("教务办公室收到文件");
    	}
    	
    	public EdOffice(String name) {
    		this.name = name;
    	}
    	
    	public String getName() {
    		return name;
    	}
    }
    

    有枝结点类Branch

    package compositepattern;
    
    import java.util.ArrayList;
    
    public class Branch extends AbstractBranch{
    
    	private ArrayList<AbstractBranch>list;
    	private String name;
    	
    	public Branch(String name) {
    		this.name = name;
    	}
    	public void receiveDoc() {
    		System.out.println(name+"收到文件");
    	}	
    	public AbstractBranch getChild(int n) {
    		return list.get(n);
    	}	
    	public void add(AbstractBranch abBranch) {
    		list.add(abBranch);
    	}	
    	public void remove(AbstractBranch abBranch) {
    		list.remove(abBranch);
    	}	
    	public String getName() {
    		return name;
    	}	
    	public void sendDoc(AbstractBranch abBranch) {
    		System.out.println(name+ "发送文件到"+abBranch.getName());
    		abBranch.receiveDoc();
    	} 	 
    }
    

    2.某软件公司为新开发的智能手机控制与管理软件提供了一键备份功能,通过该功能可以将原本存储在手机中的通信录、短信、照片、歌曲等资料一次性全部拷贝到移动存储介质(例如MMC卡或SD卡)中。在实现过程中需要与多个已有的类进行交互,例如通讯录管理类、短信管理类等,为了降低系统的耦合度,试使用外观模式来设计并编程模拟实现该一键备份功能。

    (1)外观模式设计:
    首先设计一个BackUpFacede类,里面分别创建Messages、Contacts、Photoes、Songs对象,还有一个backUp()方法,然后在四个类中实现backUp()方法。最后设计一个XMLUilt类去获取.xml配置文件中的具体类名并返回一个实例对象。
    (2)UML类图如下:
    在这里插入图片描述
    (3)运行结果如下:
    在这里插入图片描述
    (4)主要代码如下:
    BackUpFacede类

    package facadepattern;
    
    public class BackUpFacede {
    
    	private Contacts contacts = new Contacts();
    	private Messages messages = new Messages();
    	private Photoes photoes = new Photoes();
    	private Songs songs = new Songs();
    	
    	public void backUp() {
    		contacts.backUp();
    		messages.backUp();
    		photoes.backUp();
    		songs.backUp();
    	}
    }
    

    Messages、Contacts、Photoes、Songs类(此处只列举Messages类)

    package facadepattern;
    
    public class Messages {
    
    	public void backUp() {
    		System.out.println("备份短信");
    	}
    }
    

    三、出现的问题及解决方案
    如下所示,写错了.xml配置文件,忘了在类名前面加包名,导致运行结果出错。

    <?xml version="1.0"?>
    <config>
          <className>BackUpFacede</className>
    </config>
    

    解决方案:将BackUpFacede改为facadepattern.BackUpFacede

    展开全文
  • 结合实例,正确无误地绘制工厂方法模式、抽象工厂模式的模式结构图; 要求使用XML和Java反射机制来创建对象。 使用Java语言实现工厂方法模式、抽象工厂模式实例,代码运行正确无误。 二、实现过程及步骤 1.使用...

    一、题目要求

    1. 结合实例,正确无误地绘制工厂方法模式、抽象工厂模式的模式结构图;
    2. 要求使用XML和Java反射机制来创建对象。
    3. 使用Java语言实现工厂方法模式、抽象工厂模式实例,代码运行正确无误。

    二、实现过程及步骤

    1.使用工厂方法模式设计一个程序用来读取各种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器(ImageReader),例如GIF图片读取器(GifReader)用于读取GIF格式的图片、JPG图片读取器(JpgReader)用于读取JPG格式的图片。需充分考虑系统的灵活性和可扩展性。

    (1)工厂方法模式设计:

    首先设计一个抽象工厂接口ImageReader,里面有一个抽象方法Reader(),然后设计两个具体工厂GifReader,JpgReader去实现抽象工厂接口,其次再设计一个抽象产品类Picture,里面包含一个抽象Show( )方法,然后设计两个具体产品类GifPicture,JpgPicture去继承抽象产品类,最后设计一个XMLUilt类去获取.xml配置文件中的具体类名并返回一个实例对象。

    (2)UML类图如下:
    在这里插入图片描述
    (3)运行结果如下:
    在这里插入图片描述
    (4)代码:

    抽象工厂接口ImageReader

    package factorypattern;
    
    public interface ImageReader {
    	public abstract Picture Reader();
    }
    

    具体工厂GifReader,JpgReader

    package factorypattern;
    
    public class GifReader implements ImageReader {
    	@Override
    	public Picture Reader() {
    		return new GifPicture();
    	}
    }
    
    package factorypattern;
    
    public class JpgReader implements ImageReader {
    	@Override
    	public Picture Reader() {
    		return new JpgPicture();
    	}
    }
    

    抽象产品类Picture

    package factorypattern;
    
    public abstract class Picture {
    	public abstract void Show();
    }
    

    具体产品类GifPicture,JpgPicture

    package factorypattern;
    
    public class GifPicture extends Picture{
    	@Override
    	public void Show() {
    		// TODO Auto-generated method stub
    		System.out.println("读取Gif格式的图片");
    	}
    }
    
    package factorypattern;
    
    public  class JpgPicture extends Picture{
    
    	@Override
    	public void Show() {
    		// TODO Auto-generated method stub
    		System.out.println("读取Jpg格式的图片");
    	}
    }
    

    XMLUilt类

    package factorypattern;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import java.io.File;
    
    public class XMLUtil {
    	
        //该方法用于配置从XML配置文件中提取具体类名,并返回一个实例对象
    	public static Object getBean() {
    		try {
    			//创建DOM文档对象
    			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
    			DocumentBuilder builder = dFactory.newDocumentBuilder();
    			Document doc;
    			doc = builder.parse(new File("src/factorypattern/config.xml"));
    			
    			//获取包含类名的文本节点
    			NodeList n1 = doc.getElementsByTagName("className");
    			Node classNode = n1.item(0).getFirstChild();
    			String cName = classNode.getNodeValue();
    			
    			
    			Class c = Class.forName(cName);
    			Object obj = c.newInstance();
    			return obj;
    		}catch(Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    }
    

    Text类

    package factorypattern;
    
    public class Text {
    
    	public static void main(String[] args) {
    		
    		ImageReader imagereader;
    		Picture picture;
    		imagereader = (ImageReader)XMLUtil.getBean();
    		picture = imagereader.Reader();
    		picture.Show();
    
    	}
    }
    

    .xml配置文件

    <?xml version="1.0"?>
    <config>
        <className>factorypattern.GifReader</className>
        <className>factorypattern.JpgReader</className>
    </config>
    
    1. 某软件公司欲开发一套界面皮肤库,可以对桌面软件进行界面美化。不同的皮肤将提供视觉效果不同的按钮、文本框、组合框等界面元素,其结构如下图所示:
      该皮肤库需要具备良好的灵活性和可扩展性,用户可以自由选择不同的皮肤,开发人员可以在不修改既有代码的基础上增加新的皮肤。试使用抽象工厂模式设计该皮肤库,绘制类图并编程模拟实现。

    在这里插入图片描述

    (1)抽象工厂模式设计:

    首先设计一个抽象工厂接口SkinFactory,里面有三个抽象方法createButton()、createComboBox()、createTextBox(),然后设计两个具体工厂类SpringSkinFactory和SummerSkinFactory分别实现抽象工厂接口里面的三个抽象方法,其次再设计三个抽象产品类AbstractButton、AbstractComboBox、AbstractTextBox,里面包含一个抽象action( )方法,然后对应三个不同的抽象产品类分别包括两个具体产品类,AbstractButton对应于BlueButton和GreenButton,以此类推。最后设计一个XMLUilt类去获取.xml配置文件中的具体类名并返回一个实例对象。

    (2)UML类图如下:

    在这里插入图片描述
    (3)运行结果如下:
    在这里插入图片描述
    (4)代码:

    抽象工厂接口SkinFactory

    package abstractfactory;
    
    public interface SkinFactory {
    
    	public AbstractButton createButton();
    	public AbstractComboBox createComboBox();
    	public AbstractTextBox createTextBox();
    }
    

    具体工厂类SpringSkinFactory和SummerSkinFactory(此处只列举SpringSkinFactory)

    package abstractfactory;
    
    public  class SpringSkinFactory implements SkinFactory{
    
    	public AbstractButton createButton() {
    		System.out.println("Spring风格:生产绿色按钮");
    		return new GreenButton();
    	}
    	
    	public AbstractTextBox createTextBox() {
    		System.out.println("Spring风格:生产绿色文本框");
    		return new GreenTextBox();
    	}
    	
    	public AbstractComboBox createComboBox() {
    		System.out.println("Spring风格:生产绿色组合框");
    		return new GreenComboBox();
    	}
    }
    

    抽象产品类AbstractButton、AbstractComboBox、AbstractTextBox(此处只列举AbstractButton)

    package abstractfactory;
    
    public interface AbstractButton {
    
    	public void action();
    }
    

    具体产品类(此处只列举基于AbstractButton的两个具体产品类)

    package abstractfactory;
    
    public class BlueButton implements AbstractButton{
    
    	public void action() {
    		System.out.println("蓝色按钮生产成功");
    	}
    }
    
    package abstractfactory;
    
    public class GreenButton implements AbstractButton{
    
    	public void action() {
    		System.out.println("绿色按钮生产成功");
    	}
    }
    

    XMLUilt类

    package abstractfactory;
    
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import java.io.File;
    
    public class XMLUtil {
    	
        //该方法用于配置从XML配置文件中提取具体类名,并返回一个实例对象
    	public static Object getBean() {
    		try {
    			//创建DOM文档对象
    			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
    			DocumentBuilder builder = dFactory.newDocumentBuilder();
    			Document doc;
    			doc = builder.parse(new File("src/abstractfactory/config.xml"));
    			
    			//获取包含类名的文本节点
    			NodeList n1 = doc.getElementsByTagName("className");
    			Node classNode = n1.item(0).getFirstChild();
    			String cName = classNode.getNodeValue();
    				
    			Class c = Class.forName(cName);
    			Object obj = c.newInstance();
    			return obj;
    		}catch(Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    }
    

    Client类

    package abstractfactory;
    
    public class Client {
    
    	public static void main(String[] args) throws Exception{
    		
    		SkinFactory skinfactory = (SkinFactory)XMLUtil.getBean();
    		AbstractButton button = skinfactory.createButton();
    		AbstractTextBox textBox = skinfactory.createTextBox();
    		AbstractComboBox comboBox = skinfactory.createComboBox();
    		
    		button.action();
    		textBox.action();
    		comboBox.action();
    	}
    }
    

    .xml配置文件

    <?xml version="1.0"?>
    <config>
        <className>abstractfactory.SpringSkinFactory</className>
        <className>abstractfactory.SummerSkinFactory</className>
    </config>
    

    三、出现的问题及解决方案

    (1)第一个问题比较简单,工厂类与产品类之间的关系很清楚,只包含两种图片产生器以及两种格式的图片,我们需要注意的是在编程时分清接口与实现关系以及在画类图时,搞清楚箭头的指向。
    (2)第二个问题实现稍微复杂一点,需要注意在抽象产品中包含蓝色和绿色的不同按钮、文本框以及组合框,这就需要从中抽象出按钮类、文本框类以及组合框类,这里的关系稍微有点复杂,注意在编写代码的时候避免出错。
    (3)还有就是XMLUtil类中需要注意的是.xml文件的路径修改。最后在主函数的编写中创建对象时不再使用new创建对象,而是通过从xml配置文件中提取类名并返回实例对象。

    展开全文
  • 愿景:"让编程不再难学,让技术与生活更加有趣" 更多架构课程请访问 xdclass.net 目录 ...简介:什么是单例设计模式应用 备注:面试重点考查 单例设计模式: 这个是最简单设计模..
  • ③通过编程实践,理解每一种创建型设计模式的概念和内涵、结构、优缺点以及应用场景。 (2)实验内容与步骤 ①使用简单工厂模式设计一个可以创建不同几何形状( Shape)(例如圆形( Circle).、矩形 Rectangle)和三角形...
  • 创建型设计模式

    2019-08-07 00:07:47
    1、模式分类 架构模式:架构是指一个软件系统整体的组织结构。架构模式描述软件系统的组织结构的一些规则和指南。通过这些规则和指南,我们可以把预定义的、职责明确的子系统有效地组织起来。...2、设计模式的分类...
  • 创建型设计模式&结构型设计模式

    热门讨论 2016-02-01 21:34:13
    程序开发过程无法从用户那里得获得所有需求,业务流程是需求中最可能变化地方,,用户在特殊时期有不同需求,从而改变业务流程也是常见。...” 应用设计模式会让程序变得更加灵活,模块之间
  • 创建型模式主要关注对象创建过程,将对象创建过程进行封装,使客户端可以直接得到对象,而不用去关心如何创建对象。 这里共有5种创建型模式: 单例模式(Singleton) : 用于得到某类型唯一对象; 工厂方法模式...
  • 创建型模式常用是factory、builder和prototype,用于抽象和简化 singleton模式用于管理有限资源(有限资源常常需要解决并发问题,实现时需要注意)
  • 愿景:"让编程不再难学,让技术与生活更加有趣" 更多架构课程请访问 xdclass.net 目录 第1集 原生社会过渡-常见工厂设计模式 第2集 电商支付应用案例-简单工厂模式实践指南...简介:介绍常见工厂设计模式和..
  • 创建型设计模式分享

    2020-12-17 17:30:25
    闲说设计模式 信耶稣的人都要读圣经,而信OO的人都要读四人组的《设计模式》,这就是OO的圣经。 OO概念是我们的基础,OO原则 是我们的目标,而设计模式是我们的做法。 把模式装进脑子里,然后在你的设计和已有...
  • 接前文:Python与设计模式之一:创建型模式(上)2. 建造者模式建造者模式主要用于协调对象创建过程中多个步骤。常用例子是生产不同配置电脑,根据用户传入不同配置参数,返回搭配不同硬件电脑。一般来说,...
  • 春节终于结束了,大吃大喝串亲戚,肥10斤。...设计模式在开发中用很多,但是设计模式不是教科书,只是一种组织代码思想。如果你完全跟着标准的设计模式去做,我觉得你代码会冗余且复杂。记住,千万不要为了设...
  • 1、单例模式保证了 系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建和销毁对象,使用单例模式可以提高系统性能。 2、单例模式使用场景: 需要频繁进行创建和销毁对象; 创建对象时...
  • ☞23 种设计模式——创建型设计模式(5种) ☞ 23 种设计模式——结构型设计模式(7种) ☞23 种设计模式——行为型设计模式(11种) 软件设计模式使人们可以更加简单方便复用成功设计和体系结构,它通常包含以下...
  • 单例模式可以保证系统中,应用模式的类只有一个对象实例 使用场景: 业务系统全局只需要一个对象实例,比如发号器、 redis连接对象等 Spring IOC容器中的bean默认就是单例 spring boot 中的controller、service、...
  • 创建型设计模式 设计模式名称 原型模式 应用场景 1、标对象创建这一动作发自原型对象本身 2、目标对象是原型对象一个克隆。即通过Prototype模式创建对象,不仅与原型对象有相同结构,还与原型对象具有相同...
  • 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式。本章将要学习的简单工厂模式是工厂方法模式的“小弟”,它不属于GoF 23种设计模式,但在软件开发中...
  • 创建型设计模式 设计模式名称 单例模式(懒汉模式+恶汉模式) UML 应用场景 1、多个线程之间,共享一个资源或者操作同一个对象 2、整个程序控件使用全局变量,共享资源 3、大规模系统中,为了性能考虑,需要节省...
  • 创建型设计模式是一类处理对象创建设计模式,通过某种方式控制基本对象创建来避免基本对象创建时可能导致设计上问题或增加设计复杂度。 单例模式又叫单体模式,是只允许实例化一次对象类。单例模式有三...
  • 4.数据库连接池设计,一般也采用单例设计模式,数据库连接是一种数据库资源。在数据库软件系统中使用数据库连接池,可以节省打开或关闭数据库连接引起效率损耗,用单例模式维护,就可以大大降低这种损耗。5.应用....
  • 创建型设计模式——抽象工厂模式6.1 抽象工厂模式介绍6.2 抽象工厂模式的定义6.3 抽象工厂模式的使用场景6.4 抽象工厂模式的UML类图6.5 抽象工厂方法模式的简单实现6.6 Android源码中的抽象工厂方法模式实现6.7 抽象...
  • 后来还是我片面了,看到它的应用场景,是的,是我格局小了。 应用场景      1.对象之间相同或相似,即只是个别的几个属性不同的时候。      2.创建对象成本较大
  • 1/23 创建型设计模式:单例模式

    千次阅读 2020-05-27 23:08:57
    单例模式是23种设计模式最为简单一种,属于创建型设计模式一种。 其中最主要就是保证一下代码特性: 保证一个类仅有一个实例,并提供一个访问它全局访问点。 设计模式是编码思想一种应用,如果博客中...
  • 目录认识应用场景实现 认识   简单工厂模式又叫静态工厂方法...使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。 实现 public class Client {
  • 文章目录设计模式创建型模式单例模式单例设计模式介绍单例模式的三步曲**单例设计模式八种方式****饿汉式(静态常量)****饿汉式(静态代码块)**懒汉式(线程不安全)懒汉式(线程安全,同步方法)懒汉式(线程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,556
精华内容 1,022
关键字:

创建型设计模式的应用