• 设计模式第一次作业


    设计模式第一次作业

    github地址

    1、要求:某系统日志记录器要求支持多种日志记录方式,如文件记录、数据库记录等;用户可以根据要求动态选择日志记录方式。使用Factory模式来设计;如果系统中增加一个日志记录方式—控制台日志记录(ConsoleLog),类图将如何改变?

    github地址

    类图:

    日志记录图

    系统中增加一个日志记录方式—控制台日志记录(ConsoleLog):

    日志记录图改

    源码:

    //日志接口
    public interface Log {
        void write();
    }
    
    //日志工厂接口
    public interface LogFactory {
        Log produceLog();
    }
    
    //数据库日志
    public class DatabaseLog implements Log {
        @Override
        public void write() {
            System.out.print("write log to database");
        }
    }
    
    //数据库日志工厂
    public class DatabaseLogFactory implements LogFactory{
        @Override
        public Log produceLog() {
            return new DatabaseLog();
        }
    }
    
    //文件日志
    public class FileLog implements Log {
        @Override
        public void write() {
            System.out.print("write log to file");
        }
    }
    
    //文件日志工厂
    public class FileLogFactory  implements LogFactory{
        @Override
        public Log produceLog() {
            return new FileLog();
        }
    }
    
    //测试代码
    public class LogTest {
        private final String PROPERTY_KEY = "log.factory.class";
        @Test
        public void test() throws Exception{
            //从配置文件中获取工厂类型
            LogFactory logFactory = (LogFactory) TestUtil.getClassFromProperties(PROPERTY_KEY).newInstance();
            //从日志工厂中得到日志并操作
            logFactory.produceLog().write();
        }
    }
    

    2、要求:某系统为了改进数据库操作的性能,自定义数据连接对象Connection和语句对象Statement,可针对不同类型的数据库提供不同的连接对象和语句对象;用户可以通过配置文件等方式根据实际需要动态更换系统数据库;使用Abstract Factory模式来设计。

    github地址

    类图:

    数据库操作

    源码:

    //连接接口
    public interface Connection {
        void connect();
    }
    
    //语句接口
    public interface Statement {
        void execute();
    }
    
    //数据库操作工厂接口
    public interface DatabaseFactory {
        Connection produceConnection();
        Statement produceStatement();
    }
    
    
    //mysql连接
    public class MysqlConnection implements Connection {
        @Override
        public void connect() {
            System.out.println("Mysql connect success");
        }
    }
    
    //mysql语句操作
    public class MysqlStatement implements Statement{
        @Override
        public void execute() {
            System.out.println("Mysql statement execute success");
        }
    }
    
    //mysql数据库操作工厂
    public class MysqlDatabaseFactory implements DatabaseFactory {
        @Override
        public Connection produceConnection() {
            return new MysqlConnection();
        }
    
        @Override
        public Statement produceStatement() {
            return new MysqlStatement();
        }
    }
    
    //oracle连接
    public class OracleConnection implements Connection {
        @Override
        public void connect() {
            System.out.println("Oracle connect success");
        }
    }
    
    //oracle语句
    public class OracleStatement implements Statement{
        @Override
        public void execute() {
            System.out.println("Oracle statement execute success");
        }
    }
    
    //oracle数据库操作工厂
    public class OracleDatabaseFactory implements DatabaseFactory {
        @Override
        public Connection produceConnection() {
            return new OracleConnection();
        }
    
        @Override
        public Statement produceStatement() {
            return new OracleStatement();
        }
    }
    
    
    //数据库操作测试
    public class DatabaseTest {
        private final String PROPERTY_KEY = "database.factory.class";
        @Test
        public void test() throws Exception{
            //从配置文件中加载工厂类别
            DatabaseFactory databaseFactory = (DatabaseFactory) TestUtil.getClassFromProperties(PROPERTY_KEY).newInstance();
            //数据库连接
            databaseFactory.produceConnection().connect();
            //语句执行
            databaseFactory.produceStatement().execute();
        }
    }
    
    

    3、要求:KFC套餐是一个复杂对象,一般包括主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)组成部分,不同套餐有不同组成部分;KFC服务员要根据顾客要求,装配这些组成部分,构造一个完整套餐,返回给顾客;使用Builder模式来设计。

    github地址

    类图:

    kfc

    源码:

    //套餐
    public class Meal {
        private String food;
        private String drink;
    
        public String getFood() {
            return food;
        }
    
        public void setFood(String food) {
            this.food = food;
        }
    
        public String getDrink() {
            return drink;
        }
    
        public void setDrink(String drink) {
            this.drink = drink;
        }
    }
    
    //套餐创建者
    public abstract class MealBuilder {
        private Meal meal = new Meal();
    
        abstract void buildFood();
        abstract void buildDrink();
        public Meal getMeal(){
            return meal;
        }
    }
    
    //KFC服务员
    public class KFCWaiter {
        private MealBuilder mealBuilder;
    
        public void setMealBuilder(MealBuilder mealBuilder) {
            this.mealBuilder = mealBuilder;
        }
    
        public Meal constructMeal(){
            mealBuilder.buildFood();
            mealBuilder.buildDrink();
            return mealBuilder.getMeal();
        }
    }
    
    //套餐A创建者
    public class MealABuilder extends MealBuilder{
    
        @Override
        void buildFood() {
            getMeal().setFood("Hamburger");
        }
    
        @Override
        void buildDrink() {
            getMeal().setDrink("fruit juice");
        }
    }
    
    //套餐B创建者
    public class MealBBuilder extends MealBuilder{
    
        @Override
        void buildFood() {
            getMeal().setFood("fried chicken");
        }
    
        @Override
        void buildDrink() {
            getMeal().setDrink("cola");
        }
    }
    
    //KFC测试
    public class KFCTest {
        private final String PROPERTY_KEY = "kfc.builder.class";
        @Test
        public void test() throws Exception{
            KFCWaiter kfcWaiter = new KFCWaiter();
            //从配置文件加载套餐创建者
            MealBuilder mealBuilder = (MealBuilder) TestUtil.getClassFromProperties(PROPERTY_KEY).newInstance();
            //设置套餐创建者
            kfcWaiter.setMealBuilder(mealBuilder);
            //创建套餐
            Meal meal = kfcWaiter.constructMeal();
            //显示结果
            System.out.printf(" the meal contains food %s and drink %s
    ", meal.getFood(), meal.getDrink());
        }
    }
    

    4、要求:游戏中的地图:包括天空、地面、背景;人物包括人体、服装、装备等组成部分,如采用Builder模式如何设计?

    github地址

    类图:

    游戏

    源码:

    //地图
    public class Map {
        private String sky;
        private String ground;
        private String background;
    
        public String getSky() {
            return sky;
        }
    
        public void setSky(String sky) {
            this.sky = sky;
        }
    
        public String getGround() {
            return ground;
        }
    
        public void setGround(String ground) {
            this.ground = ground;
        }
    
        public String getBackground() {
            return background;
        }
    
        public void setBackground(String background) {
            this.background = background;
        }
    }
    
    //地图创建者
    public abstract class MapBuilder {
        private Map map = new Map();
    
        abstract void buildSky();
        abstract void buildGround();
        abstract void buildBackground();
    
        public Map getMap() {
           return map;
        }
    }
    
    //角色
    public class Role {
        private String body;
        private String colthing;
        private String equip;
    
        public String getBody() {
            return body;
        }
    
        public void setBody(String body) {
            this.body = body;
        }
    
        public String getColthing() {
            return colthing;
        }
    
        public void setColthing(String colthing) {
            this.colthing = colthing;
        }
    
        public String getEquip() {
            return equip;
        }
    
        public void setEquip(String equip) {
            this.equip = equip;
        }
    }
    
    //角色创建者
    public abstract class RoleBuilder {
        private Role role= new Role();
    
        abstract void buildBody();
        abstract void buildClothing();
        abstract void buildEquip();
    
        public Role getRole() {
           return role; 
       }
    }
    
    //游戏
    public class Game {
        private MapBuilder mapBuilder;
        private RoleBuilder roleBuilder;
    
        public void setMapBuilder(MapBuilder mapBuilder) {
            this.mapBuilder = mapBuilder;
        }
    
        public void setRoleBuilder(RoleBuilder roleBuilder) {
            this.roleBuilder = roleBuilder;
        }
    
        public Map constructMap(){
            mapBuilder.buildSky();
            mapBuilder.buildGround();
            mapBuilder.buildBackground();
            return mapBuilder.getMap();
        }
    
        public Role constructRole(){
            roleBuilder.buildBody();
            roleBuilder.buildClothing();
            roleBuilder.buildEquip();
            return roleBuilder.getRole();
        }
    }
    
    //地图A创建者
    public class MapABuilder extends MapBuilder {
        @Override
        void buildSky() {
            getMap().setSky("blue");
        }
    
        @Override
        void buildGround() {
            getMap().setGround("smooth");
        }
    
        @Override
        void buildBackground() {
            getMap().setBackground("nothing");
        }
    }
    
     */
    //地图B创建者
    public class MapBBuilder extends MapBuilder {
        @Override
        void buildSky() {
            getMap().setSky("black");
        }
    
        @Override
        void buildGround() {
            getMap().setGround("rough");
        }
    
        @Override
        void buildBackground() {
            getMap().setBackground("dirty");
        }
    }
    
    //角色A创建者
    public class RoleABuilder extends RoleBuilder {
        @Override
        void buildBody() {
            getRole().setBody("strong");
        }
    
        @Override
        void buildClothing() {
            getRole().setColthing("sports wear");
        }
    
        @Override
        void buildEquip() {
            getRole().setEquip("sword");
        }
    }
    
    //角色A创建者
    public class RoleABuilder extends RoleBuilder {
        @Override
        void buildBody() {
            getRole().setBody("strong");
        }
    
        @Override
        void buildClothing() {
            getRole().setColthing("sports wear");
        }
    
        @Override
        void buildEquip() {
            getRole().setEquip("sword");
        }
    }
    
    //游戏测试
    public class GameTest {
        private final String MAP_PROPERTY_KEY = "game.mapBuilder.class";
        private final String ROLE_PROPERTY_KEY = "game.roleBuilder.class";
    
        @Test
        public void test() throws Exception{
            //从配置文件加载地图创建者
            MapBuilder mapBuilder = (MapBuilder) TestUtil.getClassFromProperties(MAP_PROPERTY_KEY).newInstance();
            //从配置文件加载角色创建者
            RoleBuilder roleBuilder = (RoleBuilder) TestUtil.getClassFromProperties(ROLE_PROPERTY_KEY).newInstance();
            //设置游戏的创建者
            Game game = new Game();
            game.setMapBuilder(mapBuilder);
            game.setRoleBuilder(roleBuilder);
    
            //创建地图和角色
            Map map = game.constructMap();
            Role role = game.constructRole();
    
            //显示结果
            System.out.printf("the map sky %s ground %s background %s
    ", map.getSky(), map.getGround(), map.getBackground());
            System.out.printf("the role body %s clothing %s equip %s
    ", role.getBody(), role.getColthing(), role.getEquip());
        }
    }
    

    5、某系统需要提供一个加密模块,将用户信息(如密码等)加密之后再存储在数据库中,系统已经定义好数据库操作类。为了提高开发效率,现要重用已有的加密算法,这些算法由第三方提供,没有源码。如采用Adapter模式如何设计?

    github地址

    类图:

    数据库保存加密

    源码:

    //加密类
    public class Encryptor {
        public void encrypt(){
            System.out.println("info encrypt success");
        }
    }
    
    //数据库操作类
    public class DatabaseOperator {
        public void saveInfo(){
            System.out.println("save info to database success");
        }
    }
    
    //加密的数据库操作适配器类
    public class DatabaseEncryptOperator extends DatabaseOperator {
        private Encryptor encryptor;
    
        public DatabaseEncryptOperator(Encryptor encryptor){
            this.encryptor = encryptor;
        }
    
        @Override
        public void saveInfo() {
            encryptor.encrypt();
            super.saveInfo();
        }
    }
    
    public class EncryptTest {
        @Test
        public void test(){
            //数据库操作类指定为加密的数据库操作适配类
            DatabaseOperator databaseOperator = new DatabaseEncryptOperator(new Encryptor());
            //数据库操作
            databaseOperator.saveInfo();
        }
    }
    
  • 相关阅读:
    vs2022 搭建NET6 WebApi 接口项目《五》 接口访问限流配置
    vs2022 搭建NET6 WebApi 接口项目《二》 配置swagger
    vs2022 搭建NET6 WebApi 接口项目《一》 整体项目搭建
    vs2022 搭建NET6 WebApi 接口项目《六》 返回参数配置
    vs2022 搭建NET6 WebApi 接口项目《三》 配置跨域
    Docker 在mac上的使用
    构建煤矿物联网大数据平台思路(1)
    构建煤矿物联网大数据平台思路(2)实时数据库与时序数据库
    Redis 只能通过127.0.0.1访问,磁盘在使用中等问题...
    git 提交忽略bin obj等文件
  • 原文地址:https://www.cnblogs.com/bugLoser/p/7778450.html
Copyright © 2020-2023  润新知