`

设计模式学习

 
阅读更多
预备知识:UML图

1. 泛化generation,也就是继承。表示"is-a"关系。用实线+空心箭头表示。
如:老虎类继承自动物类

2. 实现realization,也就是实现接口。用虚线+空心箭头表示。
如:大雁类实现了飞翔接口

3. 聚合aggregation。表示"has-a"关系,聚合是弱包含关系。
如:雁群里面有大雁。
Class YanQun {
    private DaYan[] daYanArray;
}
聚合用空心菱形+直线表示。空心菱形在“雁群”端。

4. 组合composition。表示"contains-a"关系,组合是强包含关系。
如:大雁有翅膀。
Class DaYan {
    private ChiBang chiBang;
    public DaYan () {
        chiBang = new ChiBang();
    }
}
组合用实心菱形+直线表示。实心菱形在“大雁”端。

5. 关联association. 即一方知道另一方的存在。
如:企鹅与气候
Class QiE {
    private QiHou qiHou;
}
关联用实线+箭头表示,箭头指向“气候”。(因为企鹅要知道气候,所以拿箭射它)

关联分为单项关联,双向关联,自身关联。企鹅与气候为单项关联,因为只企鹅知道气候,气候不知道企鹅。

6. 依赖dependency.表示"use-a"的关系
如:动物依赖于氧气和水
abstract Class Animal {
    public xinChenDaiXie (YangQi yangQi, Shui shui) {

    }
}
依赖用虚线+箭头表示。箭头指向氧气和水。因为动物要用氧气和水做新城代谢。

设计模式

一。创建型模式
1. 简单工厂
适用场景:设计一个计算器程序,里面包含两个操作数,以及一个运算符号。



重点关注工厂类:
public class SimpleFactory {
    Operater oper = null;
    public static Operater createOperater (String operater) {
        switch (operater) {
            case "+":
                oper = new AddOperater();
                break;
            case "-":
                oper = new ReduceOperater();
                break;
            ...
        }
    }
}
客户端代码:
Operater oper = SimpleFactory.createOperater("-");
oper.setNumberA(9);
oper.setNumberB(5);
System.out.print("Result = " + oper.getResult());

总结:对于易于变化的地方(到底要实例化谁)用一个单独的类(工厂)来创建其实例。

2. 工厂方法
适用场景:设计一个计算器程序,里面包含两个操作数,以及一个运算符号。



与简单工厂不同的是,客户端调用的时候,先实例化具体工厂:
IFactory factory = new AddFactory();
Operater operater = factory.createOperater();
operater.setNumberA(9);
operater.setNumberB(5);
System.out.println("Result = " + operater.getResult);

简单工厂与工厂方法的区别?
1) 简单工厂:在工厂类中加入了逻辑判断,动态实例化类,将客户端与具体产品解耦。
缺点:在增加新功能时,如增加乘法,则需改变工厂类的逻辑,违背了开闭原则。
2) 工厂方法:去除了简单工厂的缺点。定义了一个工厂接口,让子类决定实例化哪一个类。
缺点:每增加一个产品,即运算符,都要增加一个产品工厂类,造成每个产品与相应的工厂耦合。

3. 抽象工厂:解决了工厂方法一个类只能生产一个产品的弊端。
适用场景:对已有应用系统更换数据库

工厂方法:



抽象工厂:



抽象工厂中的工厂会生产一个系列的产品,而不只是一种产品。

interfact IUser {} //定义User类型

//负责对SQLServer数据库的User类做增删改查
class SQLServerUser implements IUser {
    public USer getUser() {
        //去SQLServer对应的表中查到User,然后return
    }
    public void insert(IUser user) {
        //把user插入到SQLServer对应的user表
    }
}

//负责对Access数据库的User类做增删改查
class AccessUser implements IUser {
    public User getUser() {
        //去Access对应的表中查到User,然后return
    }
    public void insert(IUser user) {
        //把user插入到Access对应的user表
    }
}

interface IDepartment {} //定义Department类型

class SQLServerDepartment implements IDepartment {
    public Department getDepartment() {
        //去SQLServer对应的表中查到department,然后return
    }
    public void insert(IDepartment department) {
        //把department插入到SQLServer对应的department表
    }
}

class AccessDepartment implements IDepartment {
    public Department getDepartment() {
        //去SQLServer对应的表中查到department,然后return
    }
    public void insert(IDepartment department) {
        //把department插入到SQLServer对应的department表
    }
}

interface IFactory {
    public IUser createUser();
    public IUser createDepartment();
}

//生产Access数据的工厂
class AccessFactory implements IFactory {
    public IUser createUser() {
        return new AccessUser();
    }

    public IDepartment createDepartment() {
        return new AccessDepartment();
    }
}

//生产SQLServer数据的工厂
class SQLServerFactory implements IFactory {
    public IUser createUser() {
        return new SQLServerUser();
    }

    public IDepartment createDepartment() {
        return new SQLServerDepartment();
    }
}

客户端代码:
User user = new User();
Department department = new Department();

//IFactory sQLServerFactory = new SQLServerFactory();
IFactory accessFactory = new AccessFactory();
IUser accessUser = accessFactory.createUser();
accessUser.insert(user);
User u = accessUser.getUser();
IDepartment accessDepartment = accessFactory.createDepartment();
accessDepartment.insert(department);
Department d = accessDepartment.getDepartment();

从产品角度,分为两类(User类和Department类);从工厂角度,也分为两类(SQLServer类和Access类)。


4. 原型(prototype): 从一个对象为原型创建另一个对象。即:虚拟方法调用+对象的克隆。
适用场景:对象的克隆



5. 单例(singleton):保证一个类只有一个实例,且自己实例化并向整个系统提供这个实例。
使用场景:在Flex项目的仪表盘中,每次用户设置完参数,都要确保只显示一个仪表盘。
线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计为单例。
单例分为3种:懒汉式、饿汉式、登记式

1. 懒汉式单例: 在调用getInstance时实例化对象,不是线程安全的
public class Singleton {
    // 将构造器设为private
    private Singleton() {}
    // 注意此处没有final
    private static Singleton instance = null;

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
}
return instance;
    }
}

2. 饿汗式单例:在类创建的同时就已经创建好一个static final的instance,以后不再改变,所以是线程安全的。
public class Singleton {
    //将构造器设为private
    private Singleton() {}
    //在成员变量中自行实例化一个private static final的instance.
    private static final instance = new Singleton();
    //静态工厂方法
    public static Singleton getInstance() {
        return instance;
    }
}

3. 登记式单例: 把单例的实例存在一个Map中,对于已经登记过的实例,直接从Map中取并且返回,对于没有登记的,则先登记,然后返回。

public class Singleton {
    private static Map<String, Singleton> map = new HashMap<String, Singleton> ();
    static {
        Singleton instance = new Singleton();
map.put(instance.getClass().getName(), instance);
    }
    //构造器用protected修饰
    protected Singleton() {}

    //静态工厂方法
    public static Singleton getInstance(String name) {
        if (name == null) {
            name = Singleton.class.getName();
    System.out.println("name == null" + "--->name="+name);
}
if (map.get(name) == null) {
            try {
                map.put(name, (Singleton)Class.forName(name).getInstance());
    } catch (Exception e) {
                e.printStackTrace();
    }
}
return map.get(name);
    }
}

懒汉式单例与饿汉式单例的区别:
1)线程安全:饿汉式线程安全,懒汉式线程不安全,若要懒汉式也线程安全,需要在getInstance方法上加入synchronized修饰。
2)资源加载:饿汉式在类创建的时候就会实例化一个对象,不管以后是否会使用该对象,缺点是会占一定内存,优点是调用时速度更快。

6. 建造者(build):将一个对象的构建与表示分离,使同样的构建过程可以用于不同的表示。
适用场景:构建汽车



//接口Builder会定义要创建对象的各个部件
public interface Builder {
    void buildPartA(); //如汽车轮子
    void buildPartB(); //如汽车方向盘
    void buildPartC(); //如汽车发动机
}

//用一个具体的类ConcreteBuilder来创建复杂的对象
public class ConcreteBuilder implements Builder {
    Part partA, partB, partC;
    public void buildPartA() {...}
    public void buildPartB() {...}
    public void buildPartC() {...}
    public Produce getResult() {...}
}

//用一个类Director来构建对象
public class Director {
    private Builder builder;
    public Director (Builder builder) {
        this.builder = builder;
    }

    //将轮子、方向盘、发动机组装成汽车
    public void construct() {
        builder.createPartA();
builder.createPartB();
builder.createPartC();
    }
}

//客户端调用
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Produce produce = builder.getResult();

建造者模式使得用户只需要指定要构建的产品,而无需知道构建的细节。

二。结构型模式
1. 外观/门面 (Facade)
适用场景:
场景1.投资基金(一个客户只需要对于一个基金,而一个基金对应多只股票)
场景2.JDBC连DB: 对于不同的DB,SQL是不同的,但对于连接数据库时,都需要加载驱动、输入用户名密码来获取数据库连接Connection. 获取Connection的步骤可以作为Facade类。



facade应用举例:用户操作基金



class Fund {
    Stock1 gu1;
    Stock2 gu2;
    Stock3 gu3;

    public Fund() {
       gu1 = new Stock1();
       gu2 = new Stock2();
       gu3 = new Stock3();
    }

    public void buyFund() {
       gu1.buy();
       gu2.buy();
       gu3.buy();
    }

    public void sellFund() {
       gu1.sell();
       gu2.sell();
       gu3.sell();
    }
}

//客户端代码
Fond jijin = new Fund();
jijin.buy();
jijin.sell();
  • 大小: 53.4 KB
  • 大小: 73.1 KB
  • 大小: 76 KB
  • 大小: 50.9 KB
  • 大小: 79.4 KB
  • 大小: 70.6 KB
  • 大小: 101.8 KB
  • 大小: 53.6 KB
分享到:
评论

相关推荐

    《设计模式学习笔记》

    《设计模式学习笔记》主要探讨了GOF的23种设计模式以及类设计的基本原则,旨在帮助开发者理解和应用这些经过时间验证的成熟解决方案。设计模式是面向对象软件设计中的核心概念,它们为解决常见的设计问题提供了标准...

    Head First 设计模式(高清中文完整版带目录+附书源码+HeadFirst设计模式学习伴侣.rar).7z.002(2-2)

    Head First 设计模式(高清中文完整版带目录)+附书源码+HeadFirst设计模式学习伴侣.rar 又名: Head First Design Patterns 作者: (美)弗里曼(Freeman,E.) 副标题: Head First Design Patterns 简介 ·····...

    HeadFirst设计模式学习伴侣.jpg

    HeadFirst设计模式学习伴侣.jpg

    设计模式学习 ppt

    这个“设计模式学习ppt”资料包显然是一份面向初学者或大学生的教学资源,通过十四个PPT文件深入浅出地讲解了设计模式的各个方面。 首先,我们来看设计模式的基本概念。设计模式是对在特定上下文中反复出现的问题...

    Java设计模式学习.pdf

    文档中描述的是Java设计模式学习笔记,目前涉及了7种设计模式,但没有具体指明这7种模式是什么,计划后续增加更多的模式。虽然文件内容中存在OCR扫描的识别错误,但不影响我们从整体上把握设计模式的脉络和学习方法...

    java设计模式学习

    本资料“java设计模式学习”包含了对设计模式的深入理解和实际应用,通过简单实用的例子,帮助开发者掌握如何在Java项目中运用设计模式。 首先,我们要介绍的是工厂模式。工厂模式是一种创建型设计模式,它提供了一...

    设计模式学习总结.doc

    在《设计模式学习总结》中,作者通过自己的学习经历和实际应用,分享了对23种经典设计模式的理解和感悟。这篇文档主要讨论了设计模式的概念、作用、应用以及学习设计模式时应注意的误区。 设计模式起源于面向对象...

    设计模式学习资料

    Java设计模式,解说通俗易懂,推荐新手学习使用,文档中包含类图

    设计模式学习.zip

    本资源"设计模式学习.zip"聚焦于C++编程语言中的设计模式应用,是2017年的一次黑马程序员培训课程的配套代码,旨在帮助学习者通过实际的代码示例来理解和掌握设计模式。 在C++中,设计模式主要分为三大类:创建型...

    设计模式学习笔记.ppt

    设计模式学习笔记.ppt 自己写的一点学习笔记。

    设计模式学习系列2设计模式影印版

    《设计模式学习系列2设计模式影印版》作为一套学习资料,专注于介绍设计模式的核心理念与实践应用,为读者提供了一个系统性的学习框架。 设计模式主要分为三类:创建型模式、结构型模式和行为型模式。其中,创建型...

    C# 设计模式学习 源码

    本资料包“C# 设计模式学习 源码”包含了作者在学习设计模式过程中的笔记和源码示例,对于想要深入理解C#设计模式的人来说是一份宝贵的资源。 设计模式分为三大类:创建型、结构型和行为型。下面将详细介绍这些类别...

    head first设计模式学习代码

    《Head First设计模式学习代码详解》 设计模式是软件工程中的宝贵经验总结,它提供了一套通用的解决方案模板,帮助开发者在面对复杂问题时能够快速有效地进行设计和开发。Head First设计模式是一本非常受欢迎的设计...

    C++设计模式学习框架

    "C++设计模式学习框架"是一个专为学习和实践这些模式而构建的资源集合,它涵盖了各种常见的设计模式,帮助开发者深入理解并熟练应用到实际项目中。 设计模式通常分为三类:创建型模式(Creational Patterns)、结构...

    设计模式学习经典篇之菜鸟篇

    本资源“设计模式学习经典篇之菜鸟篇”旨在为初学者提供一个全面而通俗易懂的设计模式学习路径。 设计模式的核心在于重用已验证的解决方案,以提高代码的可读性、可维护性和可扩展性。根据GOF(Gamma, Helm, ...

    JAVA设计模式学习【技术文档】

    ### Java设计模式学习概述 #### 标题解读 文档标题为“JAVA设计模式学习【技术文档】”,表明这是一份专注于Java语言的设计模式学习资源。设计模式作为软件工程领域的重要组成部分,它提供了一系列面向对象设计问题...

    设计模式学习指南第一节

    《设计模式学习指南》是一份详细介绍设计模式的资源,旨在帮助开发者理解和掌握设计模式的精髓。 设计模式的学习对于任何想要提升其软件设计能力的人来说都是至关重要的。它可以帮助我们遵循一些核心的设计原则,...

    设计模式学习帮助文档中文字幕高清

    本资源包含的设计模式学习帮助文档和高清中文字幕,旨在提供一个系统化的学习路径,帮助初学者和经验丰富的开发者深入理解并应用设计模式。 设计模式分为三大类:创建型模式、结构型模式和行为型模式。创建型模式...

    C#设计模式学习笔记

    以下是对“C#设计模式学习笔记”中涉及的一些关键知识点的详细解释。 1. **设计模式的基本概念**: 设计模式是一种在特定上下文中已被证明有效的解决方案模板,它描述了如何在软件设计中解决常见问题。设计模式...

Global site tag (gtag.js) - Google Analytics