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

 

posted @ 2020-02-26 22:13  华哥好棒棒  阅读(606)  评论(0编辑  收藏  举报