设计模式

本文深入讲解了三种常用的设计模式:单例模式、简单工厂模式和装饰者模式。单例模式确保一个类只有一个实例,适用于系统中唯一存在的对象,如皇帝或老板。简单工厂模式简化了对象创建过程,通过工厂类根据参数创建不同类型的对象,如按钮工厂。装饰者模式允许在不改变原类的基础上动态扩展其功能,如给服装添加额外特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初学的几种设计模式

单例设计模式

什么是单例: 在程序运行,一个类只需要一个实例,不能出现多个实例,就叫单例。
单例的模式动机: 在一个系统或平台中,某个类的实例(对象),只需要有一个 一个朝代只能有一个皇帝,一个公司只能有一个老板
原理: 得到一个类的对象,需要通过new关键字,调用构造方法创建对象
需要完成的事项:
1)私有化构造方法;
2)在类内创建对象;
3)提供一个共有的方法,用来获取本类对象

#饿汉式

public class Boss{ 
          //属性      
           private String name;    
           private int age;     
           //私有化构造方法    
           private Boss(String name, int age){     
              this.name = name;          
              this.age = age;          }     
            //私有静态本类对象作为属性     
           private static Boss boss = new Boss("马云",12);     
           //提供共有静态方法获取本类对象      
           public static Boss getBoss(){     
           return boss;        
            }    
       }

#懒汉式

   public class Boss{ 
                    private String name;   
                    private int age;   
                   //私有构造方法     
                   private King(String name, int age){   
                        this.name = name;    
                        this.age = age;          }    
                   //私有静态本类对象    
                   private static King king;     
                  //共有静态方法获取本类对象  
                   public static King getKing(){    
                   if(king==null){        
                   king = new King("唐太宗",12);     
          }         
                  return king;    
       }   
     }

简单工厂设计模式

简单工厂解决创建对象的问题。
1.原理:多态
生活中的工厂:手机厂,电视厂,服装厂…
2.动机
考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮、矩形按钮、菱形 按钮等),这些按钮都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈 现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按 钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就 可以使用简单工厂模式。
3.优缺点:
优点:工厂类包含产品的判断逻辑,可以决定创建哪一个产品类的实例,客户端可以免除直接创建产品对象 的责任,而仅仅“消费”产品;简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于 创建对象。

缺点:由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。使用简单工厂模 式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。系统扩展困难,一旦添加新产 品就不得不修改工厂逻辑,在产品类型较多时,可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

4.简单工厂四个角色:
1 工厂角色:负责创建具体的产品。
2 父类产品: 作为所有产品的父类,使用抽象类表示
3 子类产品:具体的产品
4 客户程序:使用工厂和产品的程序 5.案例: 服装厂:生产服装 分析: 需要一个服装工厂类:工厂,类中具有生产服装的功能(创建服装对象) ClothesFactory 服装类(父 类产品):抽象类表示,Clothes 服装子类(具体产品): 普通类表示,裤子(Trousers)、T恤(TShirt)、夹克

(Jacket) 客户程序:使用工厂的程序。

  public interface Human {   
           public void say(); 
        }          
  然后定义男人和女人,同样都有说话的方法。
package com.roc.factory;
    public class Man implements Human {
        /* say method
         * @see com.roc.factory.Human#say()
         */
        @Override
        public void say() {
            System.out.println("男人");
        }
    }
 package com.roc.factory;
        public class Woman implements Human {
            @Override
            public void say() {
                System.out.println("女人");
            }
        }
        最后写一个工厂类,用来创造男人和女人。第一种方式是使用逻辑判断的方式实现的。
        package com.roc.factory;
        public class SampleFactory {
            public static Human makeHuman(String type){
                if(type.equals("man")){
                    Human man = new Man();
                    return man;
                }else if(type.equals("womman")){
                    Human woman = new Woman();
                    return woman;
                }else{
                    System.out.println("生产不出来");
                    return null;
                }            
            }
        }

最后是客户端的代码

package com.roc.factory;
public class Client {   
        Human man = SampleFactory1.makeHuman(Man.class);
        man.say();
        Human woman = SampleFactory1.makeHuman(Woman.class);
        woman.say();
    }
}

装饰者模式

装饰模式指的是在不必改变原类文件和继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对 象,也就是装饰来包裹真实的对象。 应用场景:需要扩展一个类的功能,或给一个类添加附加职责

1 抽象类 ReadFile ‐‐>read抽象方法 2 定义一些子类 ReadTextFile 读取文本文件 ReadMusicFile 读取音乐文件 ReadVideoFile 读取视频文件 3 要求:提高三个类的功能 带缓冲
3.1继承 BufferedReadTextFile继承ReadTextFile 重写 read方法
BufferedReadMusicFile继承ReadMusicFile 重写 read BufferedReadVideoFile继承ReadVideoFile 重写 read
缺点:1 类体系太庞大 2 耦合性太高
3.2装饰者设计模式 :采用组合的关系

   BufferedReadFile{        
      private ReadFile readFile;       
          public BufferedReadFile(ReadFile readFile){    
                   this.readFile=readFile;           }         
                     public void read(){             ///         
                       }     
                         }

  优点:耦合性低,提高重用性  

== 代码实现==:

抽象类

  /**
     * ckd  2019/8/9   18:55
     */
    public abstract class Person {
       private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Person() {
        }
        public Person(String name) {
            super();
            this.name = name;
        }
        public  abstract void eat();
    }
    学生类
    /**
     * ckd  2019/8/9   18:56
     */
    public class Student extends Person{
        public Student(String name) {
            super (name);
        }
    
        public Student() {
            super();
        }
        public  void eat(){
            System.out.println("学生吃饭了");
        }
    }

老师类

/**
 * ckd  2019/8/9   18:56
 */
public class Teacher extends Person{
    public Teacher(String name) {
        super( name );
    }
    public Teacher() {
        super();
    }
    public void eat(){
        System.out.println("老师开始吃饭");
    }
}

装饰类

   /**
     * ckd  2019/8/9   18:56
     */
    public class Strong {
        private  Person person;
         public Strong(Person person){
             super();
             this.person=person;
         }
         public  void eat(){
             System.out.println(person.getName()+"喝一口");
             System.out.println(person.getName()+"睡一会");
             person.eat();
         }
    }

测试类

/**
 * ckd  2019/8/9   18:56
 */
public class Test {
    public static void main(String[] args){
        Student s1=new Student( "chen" );
        Teacher t1=new Teacher( "kai" );
       /* s1.eat();
        t1.eat();*/
       Strong s3=new Strong(s1);
       s3.eat();
    }
}

生产消费者模式

设置一块缓冲区,作为仓库或者容器,生产者可以王里面放入产品,同时,消费者也可以从里面提取走产品,为了解决其中的同步问题,需要一种方法或者机制来保证两者之间的同步,为了保证同步,需要给资源加锁,确定同一时刻同一个资源只能被一个线程访问。
在这里插入图片描述
使用方法
wait:当临界资源已满或者临界资源为空时,当前线程可以使用wait方法。放弃锁,进行等待,让其他线程去执行
notify:当生产者或者消费者向缓冲区放入一块产品时,可以使用notify向其他线程发出可以执行的通知,同时放弃锁,使自己处于等待状态

public class Produce {  
      
    public Object object;  
    public ArrayList<Integer> list;//用list存放生产之后的数据,最大容量为1  
              
    public Produce(Object object,ArrayList<Integer> list ){  
        this.object = object;  
        this.list = list;  
    }  
      
    public void produce() {  
          
        synchronized (object) {  
            /*只有list为空时才会去进行生产操作*/  
            try {  
            while(!list.isEmpty()){  
                    System.out.println("生产者"+Thread.currentThread().getName()+" waiting");  
                    object.wait();  
                }   
            int value = 9999;  
            list.add(value);  
            System.out.println("生产者"+Thread.currentThread().getName()+" Runnable");  
            object.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程  
        }catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
}

public class Consumer {

public Object object;  
public ArrayList<Integer> list;//用list存放生产之后的数据,最大容量为1  
          
public Consumer(Object object,ArrayList<Integer> list ){  
    this.object = object;  
    this.list = list;  
}  
  
public void consmer() {  
      
    synchronized (object) {  
        try {  
            /*只有list不为空时才会去进行消费操作*/  
            while(list.isEmpty()){  
                System.out.println("消费者"+Thread.currentThread().getName()+" waiting");  
                object.wait();  
            }   
        list.clear();  
        System.out.println("消费者"+Thread.currentThread().getName()+" Runnable");  
        object.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程  
          
    }catch (InterruptedException e) {  
        e.printStackTrace();  
        }  
    }  
    }  
      
}  
public class ProduceThread extends Thread {  
    private Produce p;  
    public ProduceThread(Produce p){  
        this.p = p;  
    }  
    @Override  
    public void run() {  
        while (true) {  
            p.produce();  
        }  
    }  
}  

package ProduceConsumer;  
public class ConsumeThread extends Thread {  
    private Consumer c;  
    public ConsumeThread(Consumer c){  
        this.c = c;  
    }  
    @Override  
    public void run() {  
        while (true) {  
            c.consmer();  
        }  
    }  
}  

package ProduceConsumer;  
  
import java.util.ArrayList;  
  
public class Main {  
    public static void main(String[] args) {  
        Object object = new Object();  
        ArrayList<Integer> list = new ArrayList<Integer>();  
      
        Produce p = new Produce(object, list);  
        Consumer c = new Consumer(object, list);  
          
        ProduceThread[] pt = new ProduceThread[2];  
        ConsumeThread[] ct = new ConsumeThread[2];  
          
        for(int i=0;i<2;i++){  
            pt[i] = new ProduceThread(p);  
            pt[i].setName("生产者 "+(i+1));  
            ct[i] = new ConsumeThread(c);  
            ct[i].setName("消费者"+(i+1));  
            pt[i].start();  
            ct[i].start();  
        }  
    }  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值