精华内容
下载资源
问答
  • 我们提醒各位EDM从业者遵循以下几点基本原则,来保证邮件营销的效果。  正确看待对象  首先要明白邮件虽然是批量发出,但实际接收者是真实存在的用户,所以我们要正确看待每一个邮箱地址,只有把他们是真实
    对于从事EDM邮件营销的人来说,邮件营销是否有效很容易从反馈数据中体现,但某些营销邮件却无法得到期望的回应,导致这种情况的因素很多,可能忽略了一些基本的要素,也可能因为马虎而违背了规则。我们提醒各位EDM从业者遵循以下几点基本原则,来保证邮件营销的效果。

      正确看待对象

      首先要明白邮件虽然是批量发出,但实际接收者是真实存在的用户,所以我们要正确看待每一个邮箱地址,只有把他们是真实的人来看待,才能换回我们应有的回报。设想用户在接到一封内容充实的邮件,怎么会不去浏览点击呢?

      获取用户许可 

      在发送电子邮件前获得用户许可是必须的,用户希望隐私得到保护和尊重,所以对于自己许可过的邮件接收和被骚扰的发送邮件,用户的选择大家可想而知,因此获得用户许可的邮件营销是必要的。

      简化退订流程

      企业最不愿看到的就是用户退订自己的邮件,所以有部分企业不在页面放置退订按钮或放在非常不明显的位置,或将退订的步骤变得异常繁复,使用户彻底失去信心与品牌好感。建议企业正视退订邮件的用户群,在今后的营销里我们还可以使用恰当的方式来进行挽回,同时收集用户的退订信息,以保证自己的营销邮件更符合大家的需要。

      放过退订用户

      部分企业会在用户退订依然持续向其发送营销邮件,这样做会很快失去企业信誉并引起用户反感,我们建议在产品自身或企业有根本性变化时,挑选适合的内容与时间想用户发送一封介绍邮件,如果处理得当可能会重新挽回部分退订用户。

      EDM邮件营销能带来的不止是转化率,其实最重要的是给企业带来品牌推广的效果,不仅树立起良好的信誉也能与用户建立良好关系并互动维护,在做到这些的同时,相信ROI会逐步增长看到明显效果。
    展开全文
  • 面向对象五大基本原则

    万次阅读 2018-08-02 14:28:19
    以前一直认为程序中的类有使用到封装继承多态就是面向对象设计,其实不然 ...面向对象的五大基本原则 单一职责原则(SRP) 开放封闭原则(OCP) 里氏替换原则(LSP) 依赖倒置原则(DIP) 接口隔离原则(ISP) ...

     

    以前一直认为程序中的类有使用到封装继承多态就是面向对象设计,其实不然

    封装,继承,多态只是面向对象的三大特性,但是在设计程序的时候并不是说类的结构使用到了(或是体现出了)这三个特性就是面向对象,

    其实真正的面向对象设计是要符合下面的五大原则,

    面向对象的五大基本原则
    单一职责原则(SRP)
    开放封闭原则(OCP)
    里氏替换原则(LSP)
    依赖倒置原则(DIP)
    接口隔离原则(ISP)

    单一职责原则(SRP)

    •      一个类应该仅有一个引起它变化的原因(最简单,最容易理解却最不容易做到的一个设计原则)
    职员类例子:
      比如在职员类里,将工程师、销售人员、销售经理这些情况都放在职员类里考虑,其结果将会非常混乱,在这个假设下,职员类里的每个方法都要if else判断是哪种情况,从类结构上来说将会十分臃肿,并且上述三种的职员类型,不论哪一种发生需求变化,都会改变职员类!这个是大家所不愿意看到的!
     

    开放封闭原则(OCP)

    •      既开放又封闭,对扩展是开放的,对更改是封闭的!

    •      扩展即扩展现行的模块,当我们软件的实际应用发生改变时,出现新的需求,就需要我们对模块进行扩展,使其能够满足新的需求!

    更改封闭即是在我们对模块进行扩展时,勿需对源有程序代码和DLL进行修改或重新编译文件!

    这个原则对我们在设计类的时候很有帮助,坚持这个原则就必须尽量考虑接口封装,抽象机制和多态技术!

     

    里氏替换原则(LSP)

    •      子类可以替换父类并且出现在父类能够出现的任何地方

    •      这个原则也是在贯彻GOF倡导的面向接口编程!
    在这个原则中父类应尽可能使用接口或者抽象类来实现!

    子类通过实现了父类接口,能够替父类的使用地方!
    通过这个原则,我们客户端在使用父类接口的时候,通过子类实现!
    意思就是说我们依赖父类接口,在客户端声明一个父类接口,通过其子类来实现
    这个时候就要求子类必须能够替换父类所出现的任何地方,这样做的好处就是,在根据新要求扩展父类接口的新子类的时候而不影响当前客户端的使用!
     

    依赖倒置原则(DIP)

    •      传统的结构化编程中,最上层的模块通常都要依赖下面的子模块来实现,也
    称为高层依赖低层!
    所以DIP原则就是要逆转这种依赖关系,让高层模块不要依赖低层模块,所以称之为依赖倒置原则!
     

    ISP 接口隔离原则

    •      这个原则的意思是:使用多个专门的接口比使用单个接口要好的多!

    这个我有体会,在我实际编程中,为了减少接口的定义,将许多类似的方法都放在一个接口中,最后发现,维护和实现接口的时候花了太多精力,而接口所定义的操作相当于对客户端的一种承诺,这种承诺当然是越少越好,越精练越好,过多的承诺带来的就是你的大量精力和时间去维护!

    展开全文
  • 网络安全的基本原则

    2021-01-07 13:53:22
    信息安全遵循三个总体原则,通常是机密性,完整性和可用性。 机密性:这意味着信息仅由有权访问该信息的人查看或使用。必须采取适当的安全措施,以确保私人信息保持私密性,并防止未经授权的泄露和窥视。 完整性...

    当涉及到网络时,安全一直是我们无法避开的话题。数据泄露,黑客攻击,恶意软件,网络钓鱼,勒索病毒和许多其他威胁足以让很多企业头痛。20年来明辰智航一直关注网络健康,保护系统安全和网络应用的健壮性测试。
    1.信息安全的目标
    信息安全遵循三个总体原则,通常是机密性,完整性和可用性。
    机密性:这意味着信息仅由有权访问该信息的人查看或使用。必须采取适当的安全措施,以确保私人信息保持私密性,并防止未经授权的泄露和窥视。
    完整性:此原则可确保数据的完整性和准确性,并防止数据被修改。这意味着未经授权的用户对信息的任何更改都是不可能的(或至少无法检测到),并且可以跟踪授权的用户的更改。
    可用性:此原则可确保在授权用户需要时随时可以完全访问该信息。这意味着用于存储,处理和保护所有数据的所有系统必须始终稳定运行。
    在这里插入图片描述

    因此,IT安全专家提出了最佳实践,以帮助确保其信息安全。
    2.IT安全最佳实践
    明辰智航有针对众多行业和企业的实践方案。
    实用平衡保护
    大多数IT部门没有经过各种网络攻击和渗透测试,而是着重于防护最重要的系统和业务,大量的防护设备、审计设备导致业务访问慢,出现了网络安全防护和网络性能质量的平衡抉择。
    分配最低权限
    分配的权限是否满足工作需要,权限是否分配正确,访问的内容是什么、访问的时间、访问的行为操作,权限是否有越权。例如,会计方面的人员不需要查看客户数据库中的所有名称,可能需要查看销售中的数字。这意味着系统管理员需要根据人员的工作类型来分配访问权限,并且可能需要根据组织分离来进一步细化那些限制。这将确保财务在理论上比会计能够访问更多的数据和资源。会计人员不允许访问的权限是否赋予了访问权限。
    识别漏洞并提前修复
    重要服务器、应用业务需要第一时间修复,周期性的应对不同类型的攻击测试(例如黑客,DDoS攻击或仅针对员工的网络钓鱼电子邮件),测试结果帮助我们来评估各个节点、区域、部门在实际中可能面临的风险,并及时进行修复。提高全体人员的网络安全防范意识。
    攻击事件溯源
    传统安全防御体系无法捕捉到攻击者的攻击手段、攻击目的、突破口、设备指纹等信息,无法对黑客的攻击手法进行分析并升级安全防护策略。
    依托伪装代理、诱饵、蜜罐的高交互性,诱导攻击者深度入侵系统,在加上网络流量采集,对整个攻击事件进行复现,清晰掌握攻击轨迹和行为细节,明辰智航明网系统带有指纹和黑客画像等技术可以实现攻击朔源,同时清楚掌握存在的安全漏洞及风险。
    备份,备份,备份
    当发生安全破坏时,应记录该事件,实际上,即使没有发生事件,也需要经常备份尽可能多的数据。
    有时,事后发现的网络安全问题原因比较少,因此,网络回溯系统和恢复数据就成了重要途径。为防止事件的在此放生,需要我们了解整个攻击事件,对事件进行复现,有利于我我们管理和防御网络。
    周期性的安全测试和渗透测试
    安全测试则是站在防护者角度思考问题,尽量发现所有可能被攻击者利用的安全隐患,并指导其进行修复。
    渗透测试是以攻击者的角度来看待和思考问题。
    黑客在不断提高自己的技术水平,这意味着信息安全必须不断发展跟进。需要要关注和定期进行测试,进行风险评估。同时攻击事件帮助我们测试业务安全和系统安全的健壮性,并提高其安全性,从而使其他类型的黑客无法如此轻松地获得访问权限。—以上由明辰智航专注网络健康20年的—技术提供

    展开全文
  • 面向对象五大基本原则详解

    千次阅读 2018-12-06 17:27:36
    面向对象五大基本原则单一职责原则计算器实例加法类AddJiSuanQi减法类SubJiSuanQi开放封闭原则(OCP)开放封闭原则示例(书店售书)类图代码实现第一个办法:第二个办法:第三个办法:代码实现归纳变化:扩展接口再...

    单一职责原则

    一个类最好只有一个能引起变化的原因,只做一件事,单一职责原则可以看做是低耦合高内聚思想的延伸,提高高内聚来减少引起变化的原因。

    计算器实例

    通常在写计算器类是会有各种写法,简单的写法,例如:

    package Recursion;
    
    /**
     * Created by lirui on 2018/12/6.
     */
    public class JiSuanQi {
        int a;
        int b;
    
        public JiSuanQi(int a, int b) {
            this.a = a;
            this.b = b;
        }
    
        //加法
        public int add(int a, int b) {
            return a + b;
        }
    
        //减法
        public int sub(int a, int b) {
            return a - b;
        }
    }
    

    但这种写法却没有很好的按照单一职责的原则去构建,计算器不仅有加法,减法,还有乘法,除法,倘若后续要加上乘法,除法,那就要在原来的类中进行改动,添加这两个方法,但如果按照单一职责原则,一个类专注做一件事,对上一个类进行拆分,例如:

    1. 加法类AddJiSuanQi
    public class AddJiSuanQi extends  JiSuanQi {
        public AddJiSuanQi(int a, int b) {
            super(a, b);
        }
        //加法
        public int add(int a, int b) {
            return a + b;
        }
    }
    
    1. 减法类SubJiSuanQi
    public class SubJiSuanQi extends JiSuanQi {
        public SubJiSuanQi(int a, int b) {
            super(a, b);
        }
        //减法
        public int add(int a, int b) {
            return a - b;
        }
    }
    
    

    通过将加法减法分别抽出成单一的类,这样,如果后续还要加乘法,除法功能,只需再新添这两个类,而不需要在原有类中进行改动。

    开放封闭原则(OCP)

    软件实体(类,模块,函数等等)应该是可扩展的,但是不可修改。因为修改程序有可能会对原来的程序造成错误。不能修改,但是可以添加功能,尽可能的在外边添加新的类。

    开放封闭原则示例(书店售书)

    1. 类图
      在这里插入图片描述

    2. 代码实现

    /**
     * 书籍接口
     * Created by lirui on 2018/12/6.
     */
    public interface IBook {
        //书籍名称
        public String getName();
        //书籍售价
        public int getPrice();
        //书籍作者
        public String getAuthor();
    }
    
    package Book;
    
    /**
     * Created by lirui on 2018/12/6.
     */
    public class NovelBook implements IBook {
        //书籍名称
        private String name;
        //书籍的价格
        private int price;
        //通过构造函数传递书籍数据
        private String author;
    
        public NovelBook(String name, int price, String author) {
            this.name = name;
            this.price = price;
            this.author = author;
        }
    
        @Override
        public String getName() {
            return this.name;
        }
    
        @Override
        public int getPrice() {
            return this.price;
        }
    
        @Override
        public String getAuthor() {
            return this.author;
        }
    }
    
    
    package Book;
    
    import java.text.NumberFormat;
    import java.util.ArrayList;
    
    /**
     * Created by lirui on 2018/12/6.
     */
    public class BookStore {
        private final static ArrayList<IBook> bookList=new ArrayList<>();
        static {
            bookList.add(new NovelBook("三国演义",100,"罗贯中"));
            bookList.add(new NovelBook("西游记",200,"吴承恩"));
            bookList.add(new NovelBook("红楼梦",300,"曹雪芹"));
                }
        //模拟书店买书
        public static void main(String[] args) {
            NumberFormat format=NumberFormat.getCurrencyInstance();
            format.setMaximumFractionDigits(2);
            System.out.println("-=-=-=-=-=-=-=-=书店卖出书籍记录-=-=-=--=-=-=-=-");
            for (IBook book:bookList){
                System.out.println("书籍名称:"+book.getName()+"\t书籍作者:"+book.getAuthor()+"\t书籍价格:"+format.format(book.getPrice()/100.0)+"元");
            }
        }
    }
    运行结果
    -=-=-=-=-=-=-=-=书店卖出书籍记录-=-=-=--=-=-=-=-
    书籍名称:三国演义	书籍作者:罗贯中	书籍价格:¥1.00元
    书籍名称:西游记	书籍作者:吴承恩	书籍价格:¥2.00元
    书籍名称:红楼梦	书籍作者:曹雪芹	书籍价格:¥3.00元
    
    

    项目投产,书店盈利,但为扩大市场,书店决定,40元以上打8折,40元以下打9 折。如何解决这个问题呢?

    1. 第一个办法:

    修改接口。在IBook上新增加一个方法getOffPrice(),专门进行打折,所有实现类实现这个方法。
    但是这样修改的后果就是实现类NovelBook要修改,BookStore中的main方法也修改,同时Ibook作为接口应该是稳定且可靠的,不应该经常发生变化,否则接口做为契约的作用就失去了效能,其他不想打折的书籍也会因为实现了书籍的接口必须打折,因此该方案被否定。

    1. 第二个办法:

    修改实现类。修改NovelBook 类中的方法,直接在getPrice()中实现打折处理,这个应该是大家在项目中经常使用的就是这样办法,通过class文件替换的方式可以完成部分业务(或是缺陷修复)变化,该方法在项目有明确的章程(团队内约束)或优良的架构设计时,是一个非常优秀的方法。
    但是该方法还是有缺陷的,例如采购书籍人员也是要看价格的,由于该方法已经实现了打折处理价格,因此采购人员看到的也是打折后的价格,这就产生了信息的蒙蔽效果,导致信息不对称而出现决策失误的情况。该方案也不是一个最优的方案。

    1. 第三个办法:

    最优方案,通过扩展实现变化。增加一个子类 OffNovelBook,覆写getPrice方法,高层次的模块(也就是static静态模块区)通过OffNovelBook类产生新的对象,完成对业务变化开发任务。好办法,风险也小

    代码实现

    /**
     * 书籍打折类
     * Created by lirui on 2018/12/6.
     */
    public class OffNovelBook extends NovelBook {
        public OffNovelBook(String name, int price, String author) {
            super(name, price, author);
        }
        //覆写销售价格
        @Override
        public int getPrice(){
            //原价
            int prePrice=super.getPrice();
            int offPrice=0;
            if (prePrice>=200){
                offPrice=prePrice*80/100;
            }else{
                offPrice=prePrice*90/100;
            }return offPrice;
        }
    }
    

    书店类

    /**
     * Created by lirui on 2018/12/6.
     */
    public class BookStore {
        private final static ArrayList<IBook> bookList=new ArrayList<>();
        static {
            bookList.add(new OffNovelBook("三国演义",100,"罗贯中"));
            bookList.add(new OffNovelBook("西游记",200,"吴承恩"));
            bookList.add(new OffNovelBook("红楼梦",300,"曹雪芹"));
                }
        //模拟书店买书
        public static void main(String[] args) {
            NumberFormat format=NumberFormat.getCurrencyInstance();
            format.setMaximumFractionDigits(2);
            System.out.println("-=-=-=-=-=-=-=-=书店卖出书籍记录-=-=-=--=-=-=-=-");
            for (IBook book:bookList){
                System.out.println("书籍名称:"+book.getName()+"\t书籍作者:"+book.getAuthor()+"\t书籍价格:"+format.format(book.getPrice()/100.0)+"元");
            }
        }
    }
    运行结果
    -=-=-=-=-=-=-=-=书店卖出书籍记录-=-=-=--=-=-=-=-
    书籍名称:三国演义	书籍作者:罗贯中	书籍价格:¥0.90元
    书籍名称:西游记	书籍作者:吴承恩	书籍价格:¥1.60元
    书籍名称:红楼梦	书籍作者:曹雪芹	书籍价格:¥2.40元
    

    归纳变化:

    逻辑变化。只变化一个逻辑,而不涉及到其他模块,比如原有的一个算法是ab+c,现在要求ab*c,可能通过修改原有类中的方法方式来完成,前提条件是所有依赖或关联类都按此相同逻辑处理。
    子模块变化。一个模块变化,会对其他模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的,刚刚的书籍打折处理就是类似的处理模块,该部分的变化甚至引起界面的变化。

    1. 扩展接口再扩展实现:
      书店又增加了计算机类书籍,该类书还有一个独特特性:面向的是什么领域

    代码实现

    /**
     * 计算机书籍接口
     * Created by lirui on 2018/12/6.
     */
    public interface IComputerBook extends IBook{
        //计算机书籍范围
        public String getScope();
    }
    
    **
     * 计算机书籍类
     * Created by lirui on 2018/12/6.
     */
    public class ComputerBook implements IComputerBook {
       private String name;
       private int price;
       private String author;
       private String scope;
       public ComputerBook(String name,int price,String author,String scope){
           this.name=name;
           this.price=price;
           this.author=author;
           this.scope=scope;
       }
        @Override
        public String getName() {
            return this.name;
        }
    
        @Override
        public int getPrice() {
            return this.price;
        }
    
        @Override
        public String getAuthor() {
            return this.author;
        }
    
        @Override
        public String getScope() {
            return this.scope;
        }
    }
    
    /**
     * 书店
     * Created by lirui on 2018/12/6.
     */
    public class BookStore {
        private final static ArrayList<IBook> bookList=new ArrayList<>();
        static {
            bookList.add(new NovelBook("三国演义",100,"罗贯中"));
            bookList.add(new NovelBook("西游记",200,"吴承恩"));
            bookList.add(new NovelBook("红楼梦",300,"曹雪芹"));
              bookList.add(new ComputerBook("Think in Java",400,"Bruce Eckel","编程语言"));
                }
        //模拟书店买书
        public static void main(String[] args) {
            NumberFormat format=NumberFormat.getCurrencyInstance();
            format.setMaximumFractionDigits(2);
            System.out.println("-=-=-=-=-=-=-=-=书店卖出书籍记录-=-=-=--=-=-=-=-");
            for (IBook book:bookList){
                System.out.println("书籍名称:"+book.getName()+"\t书籍作者:"+book.getAuthor()+"\t书籍价格:"+format.format(book.getPrice()/100.0)+"元");
            }
        }
    运行结果
    -=-=-=-=-=-=-=-=书店卖出书籍记录-=-=-=--=-=-=-=-
    书籍名称:三国演义	书籍作者:罗贯中	书籍价格:¥1.00元
    书籍名称:西游记	书籍作者:吴承恩	书籍价格:¥2.00元
    书籍名称:红楼梦	书籍作者:曹雪芹	书籍价格:¥3.00元
    书籍名称:Think in Java	书籍作者:Bruce Eckel	书籍价格:¥4.00元
    

    里氏替换原则(LSP)

    里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

    1. 问题描述
      一个功能T有类A来完成,后来由于需求的变化,该功能T被分为了T1和T2两部分,这两部分的功能分别有类A的子类:类B和类C来完成。如果功能T1发生了变化,修改类B的同事,有可能引起T2的功能产生故障。

    2. 产生原因
      在继承关系中,基类的存在是为整个继承的结构设定一系列的规定和约束,让整个结构都按照这个规定和约束来。例如说用一个基类来描述鸟类,根据我们对鸟类的一贯认知,会在基类中通过约定有羽毛属性,有飞翔行为的是鸟类。这样在实现布谷鸟或者杜鹃鸟的时候,它都有基类中规定的属性和行为约束,但是突然有一天boss过来说把企鹅也要加进来,因为企鹅也属于鸟类。此时我们在继承了鸟类这个基类的时候,把羽毛属性和飞翔的行为都改了。此时布谷鸟或者杜鹃鸟就都如企鹅一般没了羽毛,并且不会飞翔了。

    3. 解决办法
      当使用继承的时候,使用里氏替换原则。当使用继承的时候,尽量不覆盖或重写父类的方法。当扩展父类方法的时候,保证不影响父类功能的前提下扩展。

    4. 实例

    用一个类描述猫的叫声

    /**
     * 猫
     * Created by lirui on 2018/12/6.
     */
    public class Cat {
        public void say(){
            System.out.println("喵喵喵");
        }
    }
    

    又来个高冷猫,它不叫

    /**
     1. 高冷猫
     2. Created by lirui on 2018/12/6.
     */
    public class SpcCat extends Cat {
        @Override
        public void say(){
            System.out.println("不叫了");
        }
    }
    

    根据里氏替换原则:任何出现基类的地方,都可以用子类替换。那么此刻就尴尬了,如果用里氏替换原则将它替换,那么所有的猫都变成高冷的猫了。这显然是不合理的,但是这种问题在实际应用中确实很常见的。

    Liskov于1987年提出了一个关于继承的原则“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”——“继承必须确保超类所拥有的性质在子类中仍然成立。”也就是说,当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系。

       如果用里氏替换原则来判断一个类的框架是否合理的话,继承和多态是不是就没用了?答案显然是否定的。就上
    

    面的猫的这个例子来看,喜欢叫的猫和高冷的猫显然不应该是继承关系,而是并行的关系。在处理这种情况的时候,我们只需要定义一个共同的基类,创建一个纯虚函数来实现。那么假如我们非要用到继承来实现一个框架的时候怎么办呢?此时就要遵守里氏替换原则的四层含义:

    子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法。
    子类中可以增加自己特有的方法。
    当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
    当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

     总结起来就是:子类实现父类的抽象方法优先,但是不能覆盖父类的抽象方法。但是当子类必须要实现父类的方法的时候,那么就要遵守里氏替换原则中的第三条和第四条。
    

    接口隔离原则

    接口端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。

    1. 问题描述
      当一个提供接口的类中对于它的子类来说不是最小的接口,那么它的子类在实现该类的时候就必须要实现一些自己不需要的功能。如此一来,整个系统就会变得臃肿难以维护。

    2. 问题由来
      当类A通过接口I来依赖B,类C也通过接口I来依赖D,那么对于类A和类C来说,如果接口I不是最小接口,那么类B和类D就必须要实现他们不需要的方法。

    3. 解决问题
      遵守接口隔离原则,将“胖大”接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口类来建立依赖关系。这样他们依赖的类就不需要实现他们不需要的方法。

    4. 实例
      场景:某高三学生需要进行一次模拟测试,由于文理科教学内容之别,那么他们考试内容也有区别。假如现在考试的内容有语文,数学,地理,物理这些科目。 作为文科生,他们只考语文,数学,地理;而作为理科生,他们要考语文,数学,物理。用Java来实现这个功能

    没有实现接口隔离的代码

    考试科目接口类

    public interface IExam {
    
        public void chinese();
        public void math();
        public void physics();
        public void geograp();
    }
    

    文科考试类

    public class ArtsExam implements IExam {
        @Override
        public void chinese() {
            System.out.println("语文");
        }
    
        @Override
        public void math() {
            System.out.println("数学");
        }
    
        @Override
        public void physics() {
    
        }
    
        @Override
        public void geograp() {
            System.out.println("地理");
        }
    }
    

    理科考试类

    public class PhyExam implements IExam {
        @Override
        public void chinese() {
            System.out.println("语文");
        }
    
        @Override
        public void math() {
            System.out.println("数学");
        }
    
        @Override
        public void physics() {
            System.out.println("物理");
        }
    
        @Override
        public void geograp() {
    
        }
    }
    
    如此实现的话显然是有问题的,为什么一个类里面会出现空方法这么尴尬的东西。如果现在文理科目不止这四科,增加了生物,历史等等,那是不是出现的空方法就更多了。这时候就需要使用接口隔离原则,让类之间的依赖建立在最小接口的原则上。
    
    1. 用接口隔离原则实现
      考试接口基类
    public interface IExam {
    
        public void chinese();
        public void math();
    }
    

    文科接口类

    /**
     * 文科接口类
     * Created by lirui on 2018/12/6.
     */
    public interface IArtExam extends IExam {
        public void geograp();
    }
    
    

    理科接口类

    /**
     * 理科接口类
     * Created by lirui on 2018/12/6.
     */
    public interface IPhyExam extends IExam {
        public void physics();
    }
    

    文科考试类

    public class ArtsExam implements IArtExam {
        @Override
        public void chinese() {
            System.out.println("语文");
        }
    
        @Override
        public void math() {
            System.out.println("数学");
        }
    
        @Override
        public void geograp() {
            System.out.println("地理");
        }
    }
    
    

    理科考试类

    public class PhyExam implements IPhyExam {
        @Override
        public void chinese() {
            System.out.println("语文");
        }
    
        @Override
        public void math() {
            System.out.println("数学");
        }
    
        @Override
        public void physics() {
            System.out.println("物理");
        }
    }
    

    但是在使用接口隔离原则的时候,还是需要根据情况来控制接口的粒度,接口太小会引起系统中接口泛滥,不利于维护;太大则有违背了接口隔离规则,容易出现“胖大”接口。所以一般接口中只为被依赖的类提供定制的方法即可,不要让客户去实现他们不需要的方法。

    依赖倒置原则

    简单来说
    A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
    B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

    1. 为什么要遵循依赖倒置原则
       
        很多时候我们更改一个需求,发现更改一处地方需要更改多个文件,看见很多的报错我们自己都觉得烦,我们很清醒的意识到这是因为严重的耦合导致的,所以自然要想办法解决这个问题
    2. 依赖倒置有什么好处

    简单来说,解决耦合。一般情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变动,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序与实现细节的耦合度。

    1. 例子
      公司是奇瑞和江淮公司的金牌合作伙伴,现要求开发一套自动驾驶系统,只要汽车上安装该系统就可以实现无人驾驶,该系统可以在奇瑞和江淮车上使用,只要这两个品牌的汽车使用该系统就能实现自动驾驶。

    2. 常规写法

    既然是两种不同的汽车,那我们分别定义出来,一个QQ一个JAC,代码如下:

    /**
     * 奇瑞汽车
     * Created by lirui on 2018/12/6.
     */
    public class QQ {
        public  void run(){
            System.out.println("奇瑞汽车启动");
        }
        public void stop(){
            System.out.println("奇瑞汽车停止");
        }
    }
    
    
    /**
     * 江淮汽车
     * Created by lirui on 2018/12/6.
     */
    public class JAC {
        public void run(){
            System.out.println("江淮汽车启动");
        }
        public void stop(){
            System.out.println("江淮汽车停止");
        }
    }
    
    /**
     * 自动驾驶系统
     * Created by lirui on 2018/12/6.
     */
    public class AutoSystem {
        private String mType;
        private QQ qq;
        private JAC jac;
        public AutoSystem(String mtype){
            this.mType=mtype;
            qq=new QQ();
            jac=new JAC();
        }
        public void AutoRun(){
            if ("qq".equals(mType)){
                qq.run();
            }else{
                jac.run();
            }
        }
        public void AutoStop(){
            if ("qq".equals(mType)){
                qq.stop();
            }else{
                jac.stop();
            }
        }
    }
    

    代码很简单,相信有java基础的人一看就懂了,但是缺点也很明显,扩展性特别差,现在只有两种车,if-else语句还算简单,假设以后有100种车呢?是不是要改很多文件,写很多的if-else语句,效率很低。
    那么,接下来我们开始改造。

    1. 首先观察江淮和奇瑞两个类

    完全一模一样的代码,我们开始抽离,写个抽象类或者接口都可以,这里我们写一个接口,有人纳闷为啥不写抽象类呢?根据我的个人见解,抽象类的抽象方法可以自己实现,但是接口的方法都是由子类实现的,车的功能我们具体细节我们不知道,没必要写出它的实现,所以,我们由子类实现,代码如下

    public interface ICar {
        public void run();
        public void stop();
    }
    
    1. 其次来我们看定义

    A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
    B.抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

    在上述代码中,我们的AutoSystem类严重依赖于具体的子类,比如江淮,奇瑞,依赖了低层模块,而定义里已经说明,我们应该依赖于抽象,于是我们改造AutoSystem代码
    代码如下:

    /**
     * 自动驾驶系统
     * Created by lirui on 2018/12/6.
     */
    public class AutoSystem {
       private ICar iCar;
        public AutoSystem(ICar iCar){
            this.iCar=iCar;
        }
        public void AutoRun(){
            iCar.run();
        }
        public void AutoStop(){
           iCar.stop();
        }
    }
    
    
    /**
     * 奇瑞汽车
     * Created by lirui on 2018/12/6.
     */
    public class QQ implements ICar{
        public  void run(){
            System.out.println("奇瑞汽车启动");
        }
        public void stop(){
            System.out.println("奇瑞汽车停止");
        }
    }
    
    
    /**
     * 江淮汽车
     * Created by lirui on 2018/12/6.
     */
    public class JAC implements ICar{
        public void run(){
            System.out.println("江淮汽车启动");
        }
        public void stop(){
            System.out.println("江淮汽车停止");
        }
    }
    

    这样,我们就抽出了它的共同点。正好也呼应了B点,具体应该依赖于抽象,而不是抽象依赖于具体

    展开全文
  • 面向对象的基本原则

    2011-12-09 09:49:22
    本节主要内容:面向对象的五个基本原则 一、单一职责原则(Single-Responsibility Principle):就一个类而言,应该仅有一个引起它变化的原因。  例如:写一个WinForm应用程序,需要将数据库的操作、文件的...
  • 选择GPU服务器的五大基本原则

    万次阅读 2018-11-21 20:19:43
    选择GPU服务器的五大基本原则  从性能、可编程性、灵活性等方面对CPU、GPU、FPGA、ASIC等不同类型的服务器进行了系统的比较分析,并给出了五条选择GPU服务器的基本原则: 1.考虑业务应用先选择GPU型号 2.考虑...
  • 面向对象的五个基本原则

    千次阅读 2015-09-14 15:53:11
    本节主要内容:面向对象的五个基本原则 一、单一职责原则(Single-Responsibility Principle):就一个类而言,应该仅有一个引起它变化的原因。  例如:写一个WinForm应用程序,需要将数据库的操作、文件的...
  • 透切理解面向对象三大基本特性是理解面向对象五大基本原则的基础. 三大基本特性是:封装,继承,多态  所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信...
  • 遵循这些原则进行维度建模可以保证数据粒度合理,模型灵活,能够适应未来的信息资源,违反这些原则你将会把用户弄糊涂,并且会遇到数据仓库障碍。 原则一: 载入详细的原子数据到维度结构中 维度建模应该使用最...
  • 设计B端产品的基本原则

    千次阅读 2015-07-14 17:35:40
    设计B端产品的基本原则 3年前我来到Facebook主管商业产品设计,即便之前只有C端产品经验,但我还是一头栽进了默默无闻却又举足轻重的B端市场。具体来说,我的任务是为Facebook组建商业产品团队,挖掘其作为...
  • 软件研发人员考核的基本原则

    千次阅读 2015-02-25 15:55:32
    软件研发人员的考核一直是软件企业管理的难点,总结了进行软件研发人员考核的一些基本原则,整理出来与大家共享:   要体现公司的价值观  公司的价值观体现了公司认可什么类型的人员?要挽留哪些人?提倡做...
  • 分分钟掌握设计基本原则

    千次阅读 2016-03-18 11:28:38
    在这个创意无处不在的时代,越来越多的人成为设计师。简历、论文、PPT、个人主页、博客、活动海报、给客人的邮件、名片……,处处都在考验...我们会指出4大基本概念,几乎每一个精良的设计中都用到了这4个概念。一旦认
  • 史上最完整交互设计基本原则

    千次阅读 2017-04-06 18:14:48
    摘要:如何设计出具有优秀用户体验的产品是交互设计师始终面临的一道难题,“好的产品设计一定是建立在对用户需求的...这篇翻译自国外的交互设计基本原则,是目前为止最完整的一篇,推荐收藏。本文由人人都是产品经理
  • 一、三大基本特征:封装、继承、多态 1、封装 封装就是隐藏对象的属性和实现细节,仅对外公开...这些基本原则需要我们在使用面向对象编程中慢慢领会、总结。 转载: 面向对象的三大基本特征,五大基本原则
  • 美容院成本核算的基本原则

    千次阅读 2009-11-10 17:13:00
    美容院的销售原则: A、广告宣传销售原则:广告要根据自己能力做,主要有宣传手册、宣传画、招牌广告、灯箱广告、报纸、广播、电视等,关键要在公众中树立品牌效应,让更多人知道你的美容定位。 B、美容厅内外促销...
  • 史上最完整交互设计基本原则|推荐收藏 人人都是产品经理 • 2 小时前 摘要:如何设计出具有优秀用户体验的产品是交互设计师始终面临的一道难题,“好的产品设计一定是建立在对用户需求的深刻理解上” 这句...
  •  遵循这些原则进行维度建模可以保证数据粒度合理,模型灵活,能够适应未来的信息资源,违反这些原则你将会把用户弄糊涂,并且会遇到数据仓库障碍。 二、正文  原则1、载入详细的原子数据到维度结构中  维度...
  • 遵循这些原则进行维度建模可以保证数据粒度合理,模型灵活,能够适应未来的信息资源,违反这些原则你将会把用户弄糊涂,并且会遇到数据仓库障碍。本文适用于多维建模,不使用于3NF建模。 二、正文  原则1、载入...
  • 面向对象(OOP)的五个原则:单一职责原则(SRP)、开放封闭原则(OCP)、里氏替换原则(LSP)、依赖倒置原则(DIP)、接口隔离原则(ISP)。 1.面向对象的三个特性 面向对象的三个特性: 封装性(Encapsulation...
  • 6条初创企业基本的商业原则

    千次阅读 2012-08-10 10:06:22
    除了有创意和想法以外,有一些基本的商业规则,如果对于初创企业者事先了解的话,可以让他们在创业的过程中,少走很多弯路。    Brian Hamilton是一个企业家,也是一位创业者,从他过去26年的从商经历中,他学习...
  • 上下文驱动测试的七大基本原则

    千次阅读 2007-07-23 20:08:00
    上下文驱动测试的七大基本原则 原文:www.context-driven-testing.comThe Seven Basic Principles of the Context-Driven School 1、 任何实践活动的价值依赖于它所处的上下文。2、 在某个上下文中,只有好的...
  • LINUX设备驱动程序(第3版) 第一章介绍了驱动开发和设计的基本概念与原则。主要内容为:   1.驱动程序旨在提供机制而非策略。策略是上层应用软件提供的。驱动程序提供机制意味着提供硬件可以实现的功能。所以,...
  • 随着我国经济主体与欧盟各成员国之间往来的日益频繁,学习欧盟GDPR的相关内容对企业发展至关重要。 今天SCA安全通信联盟为大家整理了GDPR中个人数据处理的6大原则——“合法公平透明”、“目的限制”、“数据最小化...
  • 超级产品的基本原则是什么? 在互联网时代,很多网站在产品中使用的是一种新的策略,那就是消息的语气。由产品操作的动词引入到一种直接且面向操作的方法,这会触发用户采取指定的行为,因为产品回答了用户的一个...
  • 六大设计原则之开闭原则

    万次阅读 多人点赞 2016-08-28 10:32:38
    开闭原则的定义开闭原则是java世界里最基础的设计原则,它指导我们如何建立一个稳定,灵活的系统。开闭原则定义如下:Software entities like classes,modules and functions should be open for extension but ...
  • 营销费用的预算管理原则和模式

    千次阅读 2017-05-25 15:45:57
    伴随着企业的规模不断发展壮大,营销费用的增长越来越高,但利润却增长乏力,顾营销费用的精细化管理已经被越来越多的企业所重视,而营销费用管理的第一步就是建立预算机制,预算规则是一个平衡性问题, 是财务和...
  • 最近三年来,做了大量的市场调研和营销战略策略的研究工作,我们发现,快消品新品上市问题虽然为行业普遍问题,但却可以通过相应的营销策略的调整和积极的准备加以规避。据此,我们创建了“快消品新品上市八原则
  • 面向对象的三个基本特征是:封装、继承、多态   封装 封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,317
精华内容 18,926
关键字:

内容营销的基本原则