设计模式示例(Java 版)

设计模式

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点

  1. 构造方法私有化
  2. 声明一个本类对象
  3. 给外部提供一个静态方法获取对象实例

两种实例方式:

  1. 饿汉式
  2. 懒汉式

在项目中为什么要使用单例,单例有什么好处?

  1. 在设计一些工具类的时候(通常工具类只有功能方法,没有属性)
  2. 工具类可能会被频繁调用

目的是为了节省重复创建对象所带来的内存消耗,从而来提高效率

能不能用构造方法+静态方法来替代单例

public class Test()
{
    public static void main(String[] args)
    {
        SginleTon1 s1 = SingleTon1.getInstance();
        s1.print();
        SginleTon1 s11 = SingleTon1.getInstance();
        s11.print();
        
        System.out.println(s1==s11);  // true
        
        SginleTon2 s2 = SingleTon2.getInstance();
        s2.print();
        SginleTon2 s22 = SingleTon2.getInstance();
        s22.print();
        
		System.out.println(s2==s22);  // true
    }
}

// 饿汉式
class SingleTon1
{
    private SingleTon1(){}
    // 在类被加载后对象被创建,到程序结束后释放
    // 占用内存的时间长,提高效率
    private static SingleTon1 s = new SingleTon1();
    public static SingleTon1 getInstance()
    {
        return s;
    }
    public void print()
    {
        System.out.println("测试方法");
    }
}

// 懒汉式 v1:在多线程访问时会有安全问题
class SingleTon2()
{
    private SingleTon2(){}
    private static SingleTon2 s;

    // 在第一次调用 getInstance 方法时,对象被创建,到程序结束后释放
    // 占用内存的时间短,效率低(懒加载/延迟加载)
    public static SingleTon2 getInstance()
    {
        if (s == null) {
            s = new SingleTon2();
        }
        return s;
    }
    public void print()
    {
        System.out.println("测试方法");
    }
}

// 用构造方法+静态方法来实现工具类,比如 Math
// 在内存静态区一直存在
class Tools
{
    private Tools(){}
    public static void print1(){}
    public static void print2(){}
}

模板方法模式(抽象类应用)

模板方法模式(Template Method):定义一个操作中的算法的骨架,而将一些可变部分的实例延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤。

public class Test{
    public static voicd main(String[] args)
    {
        UserManager um = new UserManager();
        um.action("admin", "add");  // 执行了添加操作
        um.action("guest", "add");  // 你没有操作权限,请联系管理员
    }
}

abstract class BaseManager
{
    public static void action(String name, String method) 
    {
        if ("admin".equals(name)) {
            execute(method);
        } else {
            System.out.println("你没有操作权限,请联系管理员");
        }
    }
    
    public abstract void execute(String method);
}

class UserManager extends BaseManager
{
    public void execute(String method)
    {
        // 用户是否登录的验证
        // 验证成功后才可以执行以下操作
        if ("add".equals(method)) {
            System.out.println("执行了添加操作");
        } else if ("del".equals(method)) {
            System.out.println("执行了删除操作");
        }
    }
}

class ClassManager extends BaseManager{
    // ...
}

策略模式(接口应用)

策略模式(Strategy Pattern),定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。

OO 设计原则:

  1. 面向接口编程(面向抽象编程)
  2. 封装变化
  3. 多用组合,少用继承
public class Test
{
    public static void main(String[] args)
    {
        BaseService usr = new UserService();
        usr.setISave(new FileSave());
        usr.add("2222");
    }
}

// 把可变的行为抽象出来,定义一系列的算法
// 这样的好处是这些行为可以在真正时相互替换
interface ISave
{
    public void save(String data);
}

class FileSave implements ISave
{
    public void save(String data)
    {
        System.out.println("把数据保存到文件中。。。");
    }
}

class NetSave implements ISave
{
    public void save(String data)
    {
        System.out.println("把数据保存到网络上");
    }
}


abstract class BaseService
{
    private ISave isave;
    public void setISave(ISave isave)
    {
        this.isave = isave;
    }
    public void add(String data)
    {
        System.out.println("检查数据合法性");
        isave.save(data);
        System.out.println("数据保存完毕");
    }
}

class UserService extends BaseService
{
}

简单工厂模式

是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家庭中最简单实用的模式。

public class Test
{
    public static void main(String[] args)
    {
        // 使用者和被使用者两者之间耦合,产生了依赖,当被使用者改变时,会影响到使用者
        Product phone = new Phone();
        phone.work();
        // 使用工厂模式来降低两者之间的依赖
        Product phone = ProductFactory.getProduct("phone");
    }
}

interface Product
{
    public void work();
}

class Phone implements Product
{
    public void work()
    {
        System.out.println("手机开始工作。。。");
    }
}

class Computer implements Product 
{
    public void work()
    {
        System.out.println("电脑开始工作。。。");
    }
}

// 工厂类
class ProductFactory
{
    public static Product getProduct(String name)
    {
        if ("phone".equals(name)) {
            return new Phone();
        } else if ("computer".equals(name)) {
            return new Computer();
        } else {
            return null;
        }
    }
}

静态代理模式

代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的访问。

代理模式说白了就是“真实对象”的代表,在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途。

public class Test
{
    public static void main(String[] args)
    {
        Action userAction = new UserAction();
        ActionProxy proxy = new ActionProxy(userAction);
        proxy.doAction();
    }
}

class ActionProxy implements Action
{
    private Action target;  // 被代理的对象
    
    public ActionProxy(Action target)
    {
        this.target = target;
    }
    
    // 执行操作
    public void doAction()
    {
        long startTime = System.out.currentTimeMillis();
        target.doAction();  // 执行真正的业务
        long endTime = System.out.currentTimeMillis();
        Sytem.out.println("共耗时:" + (endTime - startTime) + "ms");
    }
} 

interface Action
{
    public void doAction();
}

class UserAction implements Action
{
    public void doAction()
    {
        for (int i = 0; i < 100; i++) {
           System.out.println("用户开始工作了");
        }
    }
}

适配器模式

适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

OO 设计原则:

  1. 面向接口编程(面向抽象编程)
  2. 封装变化
  3. 多用组合,少用继承
  4. 对修改关闭,对扩展开放

例 1:

public class Test
{
    public static void main(String[] args) 
    {
        PowerA powerA = new PowerAImpl();
        work(powerA);
        
        PowerB powerB = new PowerBImpl();
        // work(powerB); 不行
        Adapter adapter = new Adapter(powerB);
        work(adapter);
    }
    
    public static void work(PowerA a)
    {
        System.out.println("正在连接。。。");
        a.insert();
        System.out.println("工作结束。。。");
    }
}

interface PowerA
{
    public void insert();
}

class PowerAImpl implements PowerA
{
    public void insert()
    {
        System.out.println("电源 A 开始工作");
    }
}

interface PowerB
{
    public void connect();
}

class PowerBImpl implements PowerB
{
    public void connect()
    {
        System.out.println("电源 B 开始工作");
    }
}

// 适配器
class Adapter implements PowerA
{
    private PowerB powerB;
    
    public Adapter(PowerB powerB)
    {
        this.powerB = powerB;
    }
    public void insert()
    {
        powerB.connect();
    }
}

例 2:

interface Animal
{
    public void sing();
    public void cry();
    public void run();
    public void swim();
}

// 适配器类
abstract class AnimalBehaviour 
{
    public void sing(){}
    public void cry(){}
    public void run(){}
    public void swim(){}
}

class Dog implements AnimalBehaviour
{
    public void run()
    {
        System.out.println("我在跑。。。");
    }
}
java设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式单例模式,建造者模式,原型模式。 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 设计模式遵循的原则有6个: 1、开闭原则(Open Close Principle)   对扩展开放,对修改关闭。 2、里氏代换原则(Liskov Substitution Principle)   只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。 3、依赖倒转原则(Dependence Inversion Principle)   这个是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle)   使用多个隔离的借口来降低耦合度。 5、迪米特法则(最少知道原则)(Demeter Principle)   一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle)   原则是尽量使用合成/聚合的方式,而不是使用继承。继承实际上破坏了类的封装性,超类的方法可能会被子类修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈挨踢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值