23种设计模式-----创建型模式、结构型模式

一、创建型模式(都是用来帮助创建对象的)

1.单例模式

  • 作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点
  • 应用:Windows的任务管理器、回收站;项目中读取配置文件的类;网站的计数器;应用程序的日志应用;数据库连接池;操作系统的文件系统;Application;Spring中的bean;Servlet;spring MVC框架/struts1框架中的控制器对象
  • 选用:占用资源小、不需要延时加载--------枚举-->饿汉           占用资源大 、需要延时    --------------  静态内部-->懒汉
  • 实现方式:

1.饿汉式(线程安全,调用效率高,不能延时加载)

public class SingLetonDemo01 {

	//类初始化时,立即加载这个对象。加载类时,天然的线程安全
	private static SingLetonDemo01  sld = new SingLetonDemo01();
	    //构造器私有化
	private SingLetonDemo01() {
	}

	//方法没有同步,调用效率高
	public static SingLetonDemo01 getsld() {
		return sld;
	}

}

2.懒汉式(线程安全,调用效率不高,可以延时加载,并发效率低)

public class SingLetonDemo02 {
	    //不初始化,临时加载,使用时再加载
	private static SingLetonDemo02 lsd;

	//构造器私有化
	private SingLetonDemo02() {
	}

	//方法必须加入同步(有同步,效率低)
	public static synchronized SingLetonDemo02 getlsd() {
		if(lsd==null) {
			lsd = new SingLetonDemo02();
		}
		return lsd;
	}
}

3.双重检测锁式(不安全,不建议使用)

4.静态内部类式(线程安全,调用效率高,可以延时加载,并发效率高)

public class SingLetonDemo03 {

	private static class SingLetonClassInstance{
		private static final SingLetonDemo03 sld = new SingLetonDemo03();
	}

	//私有构造器
	private SingLetonDemo03() {
	}

	//方法没有同步
	public static SingLetonDemo03 getsld() {
		return SingLetonClassInstance.sld;
	}
}

5.枚举单例(简单,线程安全,调用效率高,不能延时加载)

public enum SingLetonDemo04 {

	//枚举本身就是单例
	sld;

	//添加需要的操作
	public void singletonOperation() {
	}
}

2.工厂模式

实现了创建者和调用者的分离

实例化对象,用工厂方法代替new操作

将选择实现类、创建对象统一管理和控制,从而将调用者跟实现类解耦

1.简单工厂模式

  • 用来生产同一等级结构中任意产品(新增产品需要修改代码)

方法一:

public class CarFactory01 {
    //创建者
    public static Car createcar(String type) {

        if("奥迪".equals(type)) {
            return new Audi();
        }else if("奔驰".equals(type)) {
            return new Benz();
        }else {
            return null;
        }
    }
}

方法二:

public class CarFactory02 {
    //创建者
    public static Car createAudi() {
        return new Audi();
    }
    public static Car createBenz() {
        return new Benz();
    }

}

测试:

public class Client01 {
    //调用者
    public static void main(String[] args) {
        Car c1 = CarFactory01.createcar("奥迪");
        Car c2 = CarFactory01.createcar("奔驰");

        c1.run();
        c2.run();
    }
}
public class Client02 {
    //调用者
    public static void main(String[] args) {
        Car c1 = CarFactory02.createAudi();
        Car c2 = CarFactory02.createBenz();

        c1.run();
        c2.run();
    }
}

2.工厂方法模式

  • 用来生产同一等级固定产品(可新增任意产品)

汽车接口

public interface Car {
    void run();
}

汽车工厂接口

public interface CarFactory {
    Car createCar();
}

实现类

public class AudiFactory implements CarFactory{
    @Override
    public Car createCar() {
        return new Audi();
    }
}

测试

public class Client {
    public static void main(String[] args) {
        Car c1 = new AudiFactory().createCar();
        Car c2 = new BenzFactory().createCar();

        c1.run();
        c2.run();
    }
}

3.抽象工厂模式

用来生产不同产品族的全部产品(不能新增、支持新增产品族)

产品接口一:

public interface Engine {
    void run();
    void start();
}

class LuxuryEngine implements Engine{
    @Override
    public void run() {
        System.out.println("动力强");
    }

    @Override
    public void start() {
        System.out.println("启动快");
    }
}

class LowEngine implements Engine{
    @Override
    public void run() {
        System.out.println("动力弱");
    }
    @Override
    public void start() {
        System.out.println("启动慢");
    }
}

产品接口二:

public interface Seat {
    void massage();
}

class LuxurySeat implements Seat{
    @Override
    public void massage() {
        System.out.println("自动加热");
    }
}
class LowSeat implements Seat{
    @Override
    public void massage() {
        System.out.println("无自动加热");
    }
}

产品接口三:

public interface Tyre {
    void revolve();
}

class LuxuryTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨损慢");
    }
}

class LowTyre implements Tyre{
    @Override
    public void revolve() {
        System.out.println("磨损快");
    }
}

汽车工厂接口:

public interface CarFactory {
    Engine createEngine();
    Seat   createSeat();
    Tyre   createTyre();
}
public class LuxuryCarFactory implements CarFactory{

    @Override
    public Engine createEngine() {
        return new LuxuryEngine();
    }

    @Override
    public Seat createSeat() {
        return new LuxurySeat();
    }

    @Override
    public Tyre createTyre() {
        return new LuxuryTyre();
    }

}

测试:

public class Client {
    public static void main(String[] args) {
        CarFactory factory = new LuxuryCarFactory();
        Engine  e = factory.createEngine();
        e.run();
        e.start();
    }
}

4.建造者模式

Builder负责构造、Director负责装配   实现了构建和装配的解耦。

不同的构建器,相同的装配,可以做出不同的对象

相同的构建,不同的装配,也是不同的对象

汽车:

public class Car {
    private Engine engine;//发动机
    private Seat seat;//座椅
    private Tyre tyre;//轮胎

    public void run() {
        System.out.println("汽车发动");
    }

    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public Seat getSeat() {
        return seat;
    }
    public void setSeat(Seat seat) {
        this.seat = seat;
    }
    public Tyre getTyre() {
        return tyre;
    }
    public void setTyre(Tyre tyre) {
        this.tyre = tyre;
    }
}

class Engine {
    private String name;

    public Engine(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Seat{
    private String name;

    public Seat(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class Tyre{
    private String name;

    public Tyre(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

汽车构建:

public interface CarBuilder {
    Engine builderEngine();
    Seat builderSeat();
    Tyre builderTyre();
}

汽车装配:

public interface CarDirector {
    Car directorCar();
}

Hg牌汽车构建:

public class HgCarBuilder implements CarBuilder{

    @Override
    public Engine builderEngine() {
        System.out.println("构建Hg牌发动机");
        return new Engine("Hg牌发动机");
    }

    @Override
    public Seat builderSeat() {
        System.out.println("构建座椅");
        return new Seat("Hg牌座椅");
    }

    @Override
    public Tyre builderTyre() {
        System.out.println("构建轮胎");
        return new Tyre("Hg牌轮胎");
    }

}

Hg牌汽车装配:

public class HgCarDirector implements CarDirector{
    private CarBuilder builder;

    public HgCarDirector(CarBuilder builder) {
        this.builder = builder;
    }

    @Override
    public Car directorCar() {
        Engine e = builder.builderEngine();
        Seat s = builder.builderSeat();
        Tyre t = builder.builderTyre();

        //装配成汽车对象
        Car  car = new Car();
        car.setEngine(e) ;
        car.setSeat(s);
        car.setTyre(t);

        return car;
    }

}

实现:

public class Client {
    public static void main(String[] args) {
        CarDirector director = new HgCarDirector(new HgCarBuilder());

        Car car = director.directorCar();

        System.out.println(car.getEngine().getName());
        car.run();
    }
}

5.原型模式

通过new产生一个对象需要非常复杂的数据准备或访问权限,则可使用。

Cloneable接口和clone方法。

克隆羊接口:

public class Sheep implements Cloneable{ //克隆羊,多利
    private String name;
    private int age;

        @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//返回Object对象的方法
    }

        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;
        }

        public Sheep(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
}

测试浅克隆:

public class Client {
    public static void main(String[] args) throws Exception {
        Sheep s1 = new Sheep("羊驼",18);
        Sheep s2 = (Sheep)s1.clone();

        System.out.println(s1.getName());
        System.out.println(s1.getAge());

        s1.setAge(17);

        System.out.println(s1.getAge());
        System.out.println(s2.getName());
        System.out.println(s2.getAge());
    }
}

二、结构型模式(实现松藕合)

1.适配器模式

  • 目标接口(Target):具体或抽象的类,可以是接口
  • 适配的类(Adaptee):需要适配的类或适配者类
  • 适配器(Adapter):包装一个需要适配的对象,把原接口转换为目标接口

应用于旧系统改造和升级

被适配的类:

public class Adaptee {
    public void request() {
        System.out.println("完成请求需要的功能");
    }
}

适配器:

public class Adapter extends Adaptee implements Target{

    @Override
    public void handleReq() {
        super.request();
    }
}

目标接口:

public interface Target {
    void handleReq();
}

客户端类、测试:

public class Client {
    public void test(Target t) {
        t.handleReq();
    }
    public static void main(String[] args) {
        Client c = new Client();

        Target t = new Adapter();

        c.test(t);
    }
}

2.桥接模式(bridge)

处理多层继承结构、多维度变化场景,将各个维度设计成独立的继承机构,使各个维度可以独立的扩展在抽象层建立关联

应用于:JDBC、银行日志、奖金计算、OA系统消息处理

销售电脑例子

品牌维度:

public interface Brand {
    void sale() ;
}
class Lenovo implements Brand{

    @Override
    public void sale() {
        System.out.println("销售联想品牌");
    }
}
class Dell implements Brand{

    @Override
    public void sale() {
        System.out.println("销售戴尔品牌");
    }
}

电脑类型维度:

public class Computer {
    protected Brand brand;

    public Computer(Brand b) {
        this.brand = b;
    }
    public void sale() {
        brand.sale();
    }
}

class Desktop extends Computer{

    public Desktop(Brand b) {
        super(b);
    }

    public void sale() {
    super.sale();
    System.out.println("销售台式机");
    }
}

class Laptop extends Computer{

    public Laptop(Brand b) {
        super(b);
    }

    public void sale() {
    super.sale();
    System.out.println("销售笔记本");
    }
}

测试:

public class Client {
    public static void main(String[] args) {
        //销售联想牌笔记本
        Computer  c = new Laptop(new Lenovo());

        c.sale();
    }
}

3.装饰模式(decorator)

  • 抽象构件Component:真实对象和装饰对象有相同的接口
  • 具体构件ConcreteComponent:真实对象
  • 装饰Decorator:持有一个抽象构件的引用
  • 具体装饰ConcreteDecorator:负责给构件对象增加新的东西

汽车实现:

public interface ICar {
    void move();
}

//具体构件(真实对象)
class Car implements ICar{
    @Override
    public void move() {
        System.out.println("普通汽车");
    }
}

//装饰角色
class SuperCar implements ICar{
    protected ICar car;

    public SuperCar(ICar car) {
        super();
        this.car = car;
    }

    @Override
    public void move() {
    car.move();
    }
}

//具体装饰角色
class FlyCar extends SuperCar{

    public FlyCar(ICar car) {
        super(car);
    }

    private void fly() {
        System.out.println("可以天上飞");
    }

    @Override
    public void move() {
        super.move();
        fly();
    }
}
//具体装饰
class AICar extends SuperCar{

    public AICar(ICar car) {
        super(car);
    }

    private void Auto() {
        System.out.println("可以自动驾驶");
    }

    @Override
    public void move() {
        super.move();
        Auto();
    }
}

测试:

public class Client {
     public static void main(String[] args) {
        Car car = new Car();
        car.move();

        System.out.println("添加飞行功能");
        FlyCar flycar = new FlyCar(car);
        flycar.move();

        System.out.println("添加自动驾驶功能");
        AICar  aicar = new AICar(car);
        aicar.move();
    }
}

4.组合模式(composite)

用于处理树形结构,便于统一处理

应用于:操作系统资源管理器、GUI的容器层次图、XML文件解析、OA中组织结构处理、Junit单元测试框架

核心:

  • 抽象构件(Component):定义叶子和容器构件的共同点
  • 叶子(Leaf)构件:无子节点
  • 容器(Composite)构件:有容器特征,包含子节点
public interface Component {
    void operation();
}

//叶子组件
interface Leaf extends Component{
}

//容器组件
interface Composite extends Component{
    void add(Component c);
    void remove(Component c);
    Component getChild(int index);
}

5.外观模式

为子系统提供统一的入口。封装子系统的复杂性,便于客户端调用

6.享元模式FlyWeight

存在很多个完全相同或相似的对象。可以通过享元模式节省内存

--享元模式一共享的方式高效地支持大量细粒度对象的重用。

--享元模式对象能 做到共享的关键是区分内部状态和外部状态。

-内部状态:可以共享,不会随环境变化而变化。

-外部状态:不可以共享,会随着环境变化而改变。

模式实现:

  • 享元工厂类FlyweightFactory:创建并管理享元对象,享元池一般设计成键值对
  • 抽象享元类FlyWeight:接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态
  • 具体享元类ConcreteFlyWeight:为内部状态提供成员变量进行存储
  • 非共享享元类UnsharedConcreteFlyWeight:不能被共享的子类可以设计为非共享享元类

7.代理模式(proxy pattern)

  • 安全代理:屏蔽对真实角色的直接访问
  • 远程代理:通过代理类处理远程方法调用
  • 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。

静态代理(静态定义代理类):

抽象角色:

public interface Star {
    //聊天
    void talk();
    //签合同
    void signContract();
    //唱歌
    void sing();
}

代理:

public class ProxyStar implements Star{
    private Star star;

    public ProxyStar(Star star) {
        super();
        this.star = star;
    }

    @Override
    public void talk() {
        System.out.println("聊天");
    }

    @Override
    public void signContract() {
        System.out.println("签合同");
    }

    @Override
    public void sing() {
        star.sing();
    }
}

真实类:

public class RealStar implements Star{

    @Override
    public void talk() {
        System.out.println("聊天");
    }

    @Override
    public void signContract() {
        System.out.println("签合同");
    }

    @Override
    public void sing() {
        System.out.println("陈奕迅唱歌");
    }
}

测试:

public class Client {
    public static void main(String[] args) {
        Star real = new RealStar();
        Star proxy = new ProxyStar(real);

        proxy.talk();
        proxy.signContract();
        proxy.sing();
    }
}

动态代理:(动态生成代理类)

  • java.lang.reflect.Proxy -->动态生成代理类和对象
  • java.lang.reflect.InvocationHandler(处理器接口)--> 通过invoke方法实现对真是角色的代理访问。通过Proxy生成代理类对象时都要指定对应的处理器对象

代理类:

public class StarHandler implements InvocationHandler{
    Star realStar;

    public StarHandler(Star realStar) {
        super();
        this.realStar = realStar;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object object = null;

        if(method.getName().equals("sing")) {
            object = method.invoke(realStar, args);
        }
        return object;
    }
}

测试:

public class Client {
    public static void main(String[] args) {
        StarHandler handler = new StarHandler(new RealStar());

        Star proxy = (Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
                new Class[] {Star.class}, handler);

        proxy.sing();

    }
} 

原文地址:https://www.cnblogs.com/lhl0131/p/12361350.html

时间: 2024-10-01 02:47:25

23种设计模式-----创建型模式、结构型模式的相关文章

23种设计模式 - 创建型

23种设计模式研究过好几遍了,网上的解析和例子也是超多,我就不在耗费大量空间列demo例子了.为了**再研究下这个,顺便记录下体会以备日后查询. 注:类图引字互联网,但可能出处不唯一,所以不会全部列出出处. =========================简单工厂=================================================================== 1 简单工厂模式 解决的问题: 1)避免在程序中大量的使用new 描述符,因为new时需要记住目标

23种设计模式----创建型模式

创建型模式的主要关注点是:如何创建对象?它主要目的是将对象的创建和使用分离.其中包括: 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式. 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例. 工厂方法(FactoryMethod)模式:定义一个用于创建产品的接口,由子类决定生产什么产品. 抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生

设计模式(八):Bridge桥接模式 -- 结构型模式

1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度? 例子1:设想如果要绘制矩形.圆形.椭圆.正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色.绿色.蓝色等,此时至少有如下两种设计方案: •第一种设计方案是为每一种形状都提供一套各种颜色的版本. •第二种设计方案是根据实际需要对形状和颜色进行组合. 方案1: 方案2:  

设计模式(九):Composite组合模式 -- 结构型模式

1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 我们可以使用简单的对象组合成复杂的对象,而这个复杂对象有可以组合成更大的对象.我们可以把简单这些对象定义成类,然后定义一些容器类来存储这些简单对象.客户端代码必须区别对象简单对象和容器对象,而实际上大多数情况下用户认为它们是一样的.对这些类区别使用,使得程序更加复杂.递归使用的时候跟麻烦,而我们如何使用递归组合,使得用户不必对这些类进行区别呢? 3.

设计模式(十):Decorator装饰者模式 -- 结构型模式

1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继承这个类来产生一个新类—这建立在额外的代码上. 通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静态的,用户不能控制增加行为的方式和时机.如果  你希望改变一个已经初始化的对象的行为,你怎么办?或者,你希望继承许多类的行为,改怎么办?前一个,只能在于运行时完成,后者

设计模式(十二): Flyweight享元模式 -- 结构型模式

说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面向对象技术可以很好地解决系统一些灵活性或可扩展性或抽象性的问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.比如:例子1:图形应用中的图元等对象.字处理应用中的字符对象等. 2.解决方案: 享元模式(Flyweight):对象结构型模式运用

设计模式(十一):FACADE外观模式 -- 结构型模式

1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性.例子1:一个电源总开关可以控制四盏灯.一个风扇.一台空调和一台电视机的启动和关闭.该电源总开关可以同时控制上述所有电器设备,电源总开关即为该系统的外观模式设计. 2. 问题 为了降低复杂性,常常将系统划分为若干个子系统.但是如何做到各个系统之间的通信和相互依赖关系达到最小呢? 3. 解决方案 外观模式:为子系统中的一组接口提供一个一致的界面,

设计模式(十三): Proxy代理模式 -- 结构型模式

  设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ? 你有想过限制访问某个对象,也就是说,提供一组方法给普通用户,特别方法给管理员用户?以上两种需求都非常类似,并且都需要解决一个更大的问题:你如何提供一致的接口给某个对象让它可以改变其内部功能,或者是从来不存在的功能? 可以通过引入一个新的对象,来实现对真实对象的操作或者将新的对象作为真实对象

23种设计模式(15):备忘录模式

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样就能够将该对象恢复到原先保存的状态 类型:行为类 类图: 我们在编程的时候,常常须要保存对象的中间状态,当须要的时候,能够恢复到这个状态.比方,我们使用Eclipse进行编程时,假如编写失误(比如不小心误删除了几行代码),我们希望返回删除前的状态,便能够使用Ctrl+Z来进行返回.这时我们便能够使用备忘录模式来实现. 备忘录模式的结构 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢