zoukankan      html  css  js  c++  java
  • OOP编程思想:类的设计原则

    设计原则

    如果写不出设计优良的类,就发挥不出OOP的优势。发挥不出OOP的优势,很容易就会成为量产型程序员。

    下面给出一份糟糕的简易文字游戏的代码,然后进行优化

    //Room.java
    public class Room {
        public String description;
        public Room northExit;
        public Room southExit;
        public Room eastExit;
        public Room westExit;
    
        public Room(String description) 
        {
            this.description = description;
        }
    
        public void setExits(Room north, Room east, Room south, Room west) 
        {
            if(north != null)
                northExit = north;
            if(east != null)
                eastExit = east;
            if(south != null)
                southExit = south;
            if(west != null)
                westExit = west;
        }
    
        @Override
        public String toString()
        {
            return description;
        }
    }
    //Game.java
    import java.util.Scanner;
    
    public class Game {
        private Room currentRoom;
            
        public Game() 
        {
            createRooms();
        }
    
        private void createRooms()
        {
            Room outside, lobby, pub, study, bedroom;
          
            //	制造房间
            outside = new Room("城堡外");
            lobby = new Room("大堂");
            pub = new Room("小酒吧");
            study = new Room("书房");
            bedroom = new Room("卧室");
            
            //	初始化房间的出口
            outside.setExits(null, lobby, study, pub);
            lobby.setExits(null, null, null, outside);
            pub.setExits(null, outside, null, null);
            study.setExits(outside, bedroom, null, null);
            bedroom.setExits(null, null, null, study);
    
            currentRoom = outside;  //	从城堡门外开始
        }
    
        private void printWelcome() {
            System.out.println();
            System.out.println("欢迎来到城堡!");
            System.out.println("这是一个超级无聊的游戏。");
            System.out.println("如果需要帮助,请输入 'help' 。");
            System.out.println();
        }
    
        // 以下为用户命令
    
        private void printHelp() 
        {
            System.out.print("迷路了吗?你可以做的命令有:go bye help");
            System.out.println("如:	go east");
        }
    
        private void goRoom(String direction) 
        {
            Room nextRoom = null;
            if(direction.equals("north")) {
                nextRoom = currentRoom.northExit;
            }
            if(direction.equals("east")) {
                nextRoom = currentRoom.eastExit;
            }
            if(direction.equals("south")) {
                nextRoom = currentRoom.southExit;
            }
            if(direction.equals("west")) {
                nextRoom = currentRoom.westExit;
            }
    
            if (nextRoom == null) {
                System.out.println("那里没有门!");
            }
            else {
                currentRoom = nextRoom;
                System.out.println("你在" + currentRoom);
                System.out.print("出口有: ");
                if(currentRoom.northExit != null)
                    System.out.print("north ");
                if(currentRoom.eastExit != null)
                    System.out.print("east ");
                if(currentRoom.southExit != null)
                    System.out.print("south ");
                if(currentRoom.westExit != null)
                    System.out.print("west ");
                System.out.println();
            }
        }
    	
    	public static void main(String[] args) {
    		Scanner in = new Scanner(System.in);
    		Game game = new Game();
    		game.printWelcome();
    
            while ( true ) {
            		String line = in.nextLine();
            		String[] words = line.split(" ");
            		if ( words[0].equals("help") ) {
            			game.printHelp();
            		} else if (words[0].equals("go") ) {
            			game.goRoom(words[1]);
            		} else if ( words[0].equals("bye") ) {
            			break;
            		}
            }
            
            System.out.println("感谢您的光临。再见!");
            in.close();
    	}
    
    }
    
    
    消除代码复制

    明显看到下面这段代码在Game.java中有重复

    		System.out.println("现在你在" + currentRoom);
            System.out.print("出口有:");
            if(currentRoom.northExit != null)
                System.out.print("north ");
            if(currentRoom.eastExit != null)
                System.out.print("east ");
            if(currentRoom.southExit != null)
                System.out.print("south ");
            if(currentRoom.westExit != null)
                System.out.print("west ");
            System.out.println();
    

    可以做成函数在原处调用

    //Game.java
    public void printchoice(){
    	System.out.println("现在你在" + currentRoom);
        System.out.print("出口有:");
        ......
    }
    
    用封装来降低耦合
    //Room.java
    public class Room {
        private String description;
        private Room northExit;
        private Room southExit;
        private Room eastExit;
        private Room westExit;
    
        public Room(String description){
            this.description = description;
        }
    
        public  String showExit(){
            StringBuffer re =new StringBuffer();
            if(this.eastExit!=null){
                re.append("east ");
            }
            if(this.westExit!=null){
                re.append("west ");
            }
            if(this.southExit!=null){
                re.append("south ");
            }
            if(this.northExit!=null){
                re.append("north ");
            }
            return re.toString();
        }
        
        public void setExits(Room north, Room east, Room south, Room west) {
            if(north != null)
                northExit = north;
            if(east != null)
                eastExit = east;
            if(south != null)
                southExit = south;
            if(west != null)
                westExit = west;
        }
    
        public  Room nextRoom(String obj){
            Room re=null;
            if(obj.equals("north"))
                re = this.northExit;
            else if(obj.equals("east"))
                re = this.eastExit;
            else if(obj.equals("south"))
                re = this.southExit;
            else if(obj.equals("west"))
                re = this.westExit;
            return re;
        }
    
        @Override
        public String toString(){
            return description;
        }
    }
    
    

    当然此时的Game.java

    import java.util.Scanner;
    
    public class Game {
        private Room currentRoom;
    
        public Game(){
            createMap();
        }
    
        private void createMap(){
            Room outside, lobby, pub, study, bedroom;
          
            //	制造房间
            outside = new Room("城堡外");
            lobby = new Room("大堂");
            pub = new Room("小酒吧");
            study = new Room("书房");
            bedroom = new Room("卧室");
            
            //	初始化房间的出口
            outside.setExits(null, lobby, study, pub);
            lobby.setExits(null, null, null, outside);
            pub.setExits(null, outside, null, null);
            study.setExits(outside, bedroom, null, null);
            bedroom.setExits(null, null, null, study);
    
            currentRoom = outside;  //	从城堡门外开始
        }
    
        private  void printChoice(){
            System.out.println("现在你在" + currentRoom);
            System.out.print("出口有:");
            String info = currentRoom.showExit();
            if(info != null){
                System.out.printf(info);
            }
            else{
                System.out.print("you have jump into a trap.over.");
            }
            System.out.println();
        }
    
        private void printWelcome() {
            System.out.println();
            System.out.println("欢迎来到城堡!");
            System.out.println("这是一个超级无聊的游戏。");
            System.out.println("如果需要帮助,请输入 'help' 。");
            System.out.println();
            printChoice();
        }
    
        // 以下为用户命令
    
        private void printHelp(){
            System.out.print("迷路了吗?你可以做的命令有:go bye help");
            System.out.println("如:	go east");
        }
    
        private void goRoom(String direction){
            Room nextRoom = currentRoom.nextRoom(direction);
            if (nextRoom == null) {
                System.out.println("那里没有门!");
            }
            else {
                currentRoom = nextRoom;
                printChoice();
            }
        }
    	
    	public static void main(String[] args) {
    		Scanner in = new Scanner(System.in);
    		Game game = new Game();
    		game.printWelcome();
            while ( true ) {
            		String line = in.nextLine();
            		String[] words = line.split(" ");
            		if ( words[0].equals("help") ) {
            			game.printHelp();
            		} else if (words[0].equals("go") ) {
            			game.goRoom(words[1]);
            		} else if ( words[0].equals("bye") ) {
            			break;
            		}
            }
            
            System.out.println("感谢您的光临。再见!");
            in.close();
    	}
    
    }
    
    
    以框架+数据代替硬编码提高程序可扩展性

    可扩展性的指的是代码的某些部分不需要经过修改就能适应将来可能的变化

    低耦合:类与类间的关系越松越好
    聚合:一个类或一个方法应该负责一个聚合的任务,一个方法应该实现一个逻辑操作,而一个类应该代表一定类型的实体。以此来实现重用

    用接口来实现聚合
    用容器增加灵活性

    //Room.java
    import java.util.HashMap;
    
    public class Room {
        private String description;
        private HashMap<String,Room> exit = new HashMap<String, Room>();
    
        public Room(String description){
            this.description = description;
        }
    
        public void setExit(String direction , Room room){
            exit.put(direction,room);
        }
    
        public  String showExit(){
            StringBuffer re =new StringBuffer();
            for(String s :exit.keySet()){
                re.append(s);
                re.append(" ");
            }
            return re.toString();
        }
    
        public  Room nextRoom(String obj){
            Room re=null;
            re = exit.get(obj);
            return re;
        }
    
        @Override
        public String toString()
        {
            return description;
        }
    }
    
    //Game.java中的设置地图部分
    private void createMap(){
            Room outside, lobby, pub, study, bedroom;
          
            //	制造房间
            outside = new Room("城堡外");
            lobby = new Room("大堂");
            pub = new Room("小酒吧");
            study = new Room("书房");
            bedroom = new Room("卧室");
            
            //	初始化房间的出口
            outside.setExit("west",lobby);
            outside.setExit("south",study);
            outside.setExit("north", pub);
            lobby.setExit("east",  outside);
            pub.setExit("west", outside);
            study.setExit("west",outside);
            study.setExit("south",bedroom);
            bedroom.setExit("north",study);
    		//此处我们可随意增加down,up,等等的新的Room关系,而不用修改Room类
    		//容器使得Room类更加灵活
            currentRoom = outside;  //	从城堡门外开始
        }
    

    还有一处硬编码为命令的判断,即go,bye,help
    若增加新的命令,实现命令本身的功能后,还要维护命令分发过程的代码
    同样用容器修改

    import java.util.HashMap;
    import java.util.Scanner;
    
    interface Handler{
        public void handle(String str);
    }
    
    public class Game {
        private Room currentRoom;
        private HashMap<String,Handler> handlers = new HashMap<>();
    
        public Game(){
            createMap();
            handlers.put("go", this::goRoom);
            handlers.put("help", (str -> printHelp()));
            handlers.put("bye", str -> {
                System.out.println("感谢您的光临。再见!");
                System.exit(0);
            });
        }
    
        //Game.java中的设置地图部分
        private void createMap(){...}
    
        private  void printChoice(){...}
    
        private void printWelcome() {...}
    
        // 以下为用户命令
    
        private void printHelp(){...}
    
        private void goRoom(String direction){...}
    
        private void play(){
            Scanner in = new Scanner(System.in);
            while ( true ) {
                String line = in.nextLine();
                String[] words = line.split(" ");
                String value = null;
                if(words.length>1){
                    value = words[1];
                }
                Handler handler = handlers.get(words[0]);
                if(handler!=null){
                    handler.handle(value);
                }else {
                    System.out.println("我不明白你的意思,请使用help命令");
                }
    //            if ( words[0].equals("help") ) {
    //                printHelp();
    //            } else if (words[0].equals("go") ) {
    //                goRoom(words[1]);
    //            } else if ( words[0].equals("bye") ) {
    //                break;
    //            }
            }
        }
    
        public static void main(String[] args) {
            Game game = new Game();
            game.printWelcome();
            game.play();
        }
    
    }
    

    通过以上设计,当要加入新的命令时,只需定义新的handler,主程序逻辑无需变化


    2019/7/25更新

  • 相关阅读:
    ETL工具主流产品
    深入了解当前ETL中用到的一些基本技术
    用C#实现通用守护进程
    80端口被system占用的问题
    Python Web 性能和压力测试 multi-mechanize
    [python]用profile协助程序性能优化
    python代码优化技巧
    转:Java学习路线图
    SecureCRT 颜色
    深度学习(Deep Learning)算法简介
  • 原文地址:https://www.cnblogs.com/kafm/p/12721857.html
Copyright © 2011-2022 走看看