четверг, 26 сентября 2013 г.

Substitution Model

 Элементы програмирования

Любой нетривиальный язык программирования имеет:
1) элементарные выражения, представляющие наиболее простые элементы.
2) способы комбинирования первых.
3) механизм для абстрагирования сложных и комбинированных выражений под одним именем.

В Scala все выражения, и любое выражение должно превратиться в конце концов в конкретное значение.  В Scala за это отвечает  Substitution Model, задача этого модуля, циклически выполнять вложенные выражения в друг друга, пока из них не останется конкретное значение.

В функциональном программировании есть две стратегии выполнения(Evaluation Strategy)
1) Call By Value
2) Call By Name

Каждая из стратегий выгодна в разных конкретных случаях. Но чаще всего Scala используется СBV, в большинстве случаев этого оправдано.

Но когда в случае

def someOperation(x: Int, y: Int): Int = 1

someOperation(1+2, loop)

Мы зациклимся на втором шаге. Но если второму параметру применить стратегию оценки  СBN, то міы спокойно пройдем программу

Чтобы сменить дефолтовую стратегию на  СBN,  нужно интересуемый параметр объявить:
x: Int -  СBV
x:=> Int -  СBN


Поэтому предыдущее объявленеи нужно подредактировать:
def someOperation(x: Int, y: => Int): Int = 1

someOperation(1+2, loop)// так бесконечного цикла не будет
В зависимости от реализации функции может быть более выгодной та или иная стратегия.

суббота, 21 сентября 2013 г.

Как работает внутри Spring Web Portlet

Перед нашими контроллерами происходит следующее:
0. Первое с чего все начинается это идет вызов одного из методов FrameworkPortlet (обращение вообщето идет в DispatcherPortlet, который расширяет первый, но реализация методов находится в его родителе), в зависимости от фазы портлетного запроса.
// Delegate action requests to processRequest/doActionService.
void processAction(ActionRequest req, ActionResponse resp){..}
// Delegate render requests to processRequest/doRenderService.
void doDispatch(RenderRequest req, RenderResponse resp){...}
void serveResource(ResourceRequest request, ResourceResponse response){...}
void processEvent(EventRequest request, EventResponse response){...}

но все они делают в нутри одно и тоже
{
   processRequest(req, resp);

}

1. org.springframework.web.portlet.DispatcherPortlet extends FrameworkPortlet
  void processRequest(req, resp) //in FrameworkPortlet

         //Получается фаза жизненного цикла портлетного запроса
         String phase = (String) req.getAttribute(PortletRequest.LIFECYCLE_PHASE);

         //на основании фазы выбирается в условиях подходящий обработчик,
         //что является немного странным для меня - зачем все перенаправлять в один
         // метод, чтобы потом снова разделять? - например
         if (PortletRequest.ACTION_PHASE.equals(phase)) {
   doActionService((ActionRequest) request, (ActionResponse) response);
}


        // в конце метода не зависимо от успеха, запускается событие что портлетный запрос обработан
        this.portletApplicationContext.publishEvent(
new PortletRequestHandledEvent(this,
getPortletConfig().getPortletName(),
                                                                request.getPortletMode().toString(),
(request instanceof ActionRequest ? "action" : "render"),
request.getRequestedSessionId(),
                                                                getUsernameForRequest(request),
processingTime, failureCause));   


2. org.springframework.web.portlet.DispatcherPortlet
    void doActionService(req, resp)
            HandlerExecutionChain mappedHandler; //получает инстанцию НашКлассКонтроллера
            mappedHandler = getHandler(req);

            //определяет что за обработчик у нас, выбирая из двух типов либо контроллер у нас расширяет спринговый контроллер, либо помечен аннотациями
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
     
            //например у нас ha instanceof
            //org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter
            //handleAction потому что у нас фаза Action,
            //который внутри делает то, что вызывает ModelAndView doHandle(req, resp, handler),
            //проверяет чтобы результат обязательно был null потомучто это фаза Action
            ha.handleAction(req, resp, mappedHandler.getHandler());
                          

вторник, 10 сентября 2013 г.

Как получить вебконтент

В Java:
String xmlRequest = PortletRequestUtil.toXML(request, response);

ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
JournalArticleDisplay articleDisplay = JournalContentUtil.getDisplay(
            themeDisplay.getLayout().getGroupId(),
            articleIdStr,
            null,
            themeDisplay.getLanguageId(),
            xmlRequest);
articleDisplay.getContent();

В JSP:
<%@ page import="com.liferay.portal.kernel.util.WebKeys" %>
<%@ page import="com.liferay.portal.theme.ThemeDisplay" %>

<liferay-ui:journal-article articleId="${articleId}"
                                                groupId="<%= ((ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY)).getPortletGroupId() %>"/>
                

пятница, 6 сентября 2013 г.

jMockit. State-based testing and Fakes

Один из двух подходов jMockit
Построено на реализации:
State-based testing не фокусируется на взаимодействии между тестируемым классом/юнитом и его зависимостями, а -- на саммих данных которыми обмениваются обьекты. Тесты пишутся не из перспективы теструемого класса, а с перспективы используемых классов, и не важно юнит это или депенденси. Главное в этим виде тесрирования сделать сверку в конце тестового метода, чтобы наши предположения совпали.

Понятия фейков характерны для интеграционного тестирования, где мы вяжемся на какието внешние сервисы, где мы их имитируем и не зависим от их текущего состояния.

Static Initializer Block

Блок загрженного в JVM класса, который вызывается только один раз до вызова конструктора класса или его метода мейн. Тоесть если мы создаем инстанцию класса, то только в этот момент будет вызван этот блок, все последующие создания обьектов уже этот блок вызывать не будут, таже история с методом мейн.

Правила:

  1. Код пишется в блоке static { }, который ставится в пределах класса.
  2. Блок ничего не возвращает - return.
  3. Никаких обращений к инстанции - this, super.
  4. Может выкидывать только  Unchecked Exceptions( инстанции классов RuntimeException, Error и их наследники).

Используется это для:

  1. Загрузка драйверов и другого в пространство имен (For example ‘Class.forName(“com.mysql.jdbc.Driver”)’).
  2. Проинициализировать сложные статические поля класса один раз(final static).
  3. Логирование.
  4. Создание и распарсивание подготовленных SQL-выражений. 

 
class Loader {
    static final String theName = "The Loader";
    static {
        System.out.println("Loader.static");
    }
    Loader() {
        System.out.println("Loader.Loader()");
    }
}


class Test extends Loader {
 final static Integer i;
 
    static {     
        System.out.println( "Test.static");
        i = new Integer(5);
    }
    
    {
     System.out.println( "Test.non-static");
    }
    
    Test() {
        System.out.println( "Test.Test()");
    }
    public static void main( String [] args ) {
        System.out.println( "Test.main");
        Test t = new Test();
        Test t2 = new Test();
        Test t3 = new Test();
        System.exit(0);
    }
}
Loader.static
Test.static
Test.main
Loader.Loader()
Test.non-static
Test.Test()
Loader.Loader()
Test.non-static
Test.Test()
Loader.Loader()
Test.non-static
Test.Test()

Java создание инстанций из классов Java

Если мы наследуем какой-то класс, то при создании нашего обьекта, если мы явно не вызываем определенный конструктор super([..]); будут вызваны все конструкторы без параметров вверх по цепочке (созданы инстанции каждого предка, чтобы мочь вызывать его методы и пользоваться полями - получается такой класстер инстанций, который воспринимается как одна).
Если у нашего предка, есть контруктор с параметрами и мы при определение наследника не вызываем супером конструктор отца, то компилятор выдаст ошибку - он не знает как создавать инстанцию предка - нужно либо явно вызывать существующий конструтор, либо определить отцовскому классу конструктор без параметров.

вторник, 3 сентября 2013 г.

Разработка ПО: факты против мифов

Вот наиболее распространенные мифы и факты, которые их опровергают.

Миф #1. Разработку ПО можно ускорить
Девять беременных женщин не родят ребенка за месяц. Добавление людей в отстающий проект только увеличит отставание. (Брукс)

Существует оптимальное, с точки зрения затрат, время выполнения графика для первой поставки. ВРЕМЯ [мес.] = 2,5 (ТРУДОЕМКОСТЬ [чел.* мес.])^1/3. Кривая стоимости резко растет, если запланированный график короче оптимального. Практически ни один проект невозможно завершить быстрее, чем за 3/4 расчетного оптимального графика вне зависимости от количества занятых в нем людей. (Барри Боэм

Наиболее эффективно программисты работают без жестких сроков. Сверхурочные и авралы снижают общую производительность. (Демарко)

Миф #2. Проблемы разработки ПО можно решить при помощи инструментов и процессов
Применение новых инструментов снижают производительность, но если повезет, может ее повысить на 2-20% (Гласс)

Существуют десятки методологий, но ни одна не гарантирует результат. Коуберн не обнаружил корреляции между успехом/провалом проектов и методологиями, которые применялись в проектах, будь то процессы, сертифицированные по CMMI Level 5 или процессы, построенные по принципу «как получится». Его вывод. Успешность программного проекта на 100% определяется людьми.

Миф #3. Разрабатывать ПО просто
Много лет только 1/3 проектов укладывается в треугольник: качество-стоимость-срок (Standish Group). Отраслевой прирост производительности составляет 3-5% в год (Демарко). Производительность программистов с похожим стажем и опытом могут отличаться в 10 раз (Брукс) или даже в 28 раз (Гласс).

Миф #4. Железный треугольник проекта
Разработка продукта длилась 5 лет вместо одного года. Бюджет проекта был превышен более чем в 5 раз. Это — провал? Нет — это был Microsoft Word!

Ограниченные усилия могут принести колоссальный эффект. Большинство выдающихся программных продуктов создано студентами «в гараже».

Миф #5. Работу программистов нельзя измерить
Нельзя измерить работу отдельного программиста. Что будем мерить, то и получим. Но надо измерять работу проектной команды. Обязательно.
  • Процент протестированных вариантов использования.
  • Средняя производительность, SLOC в день на каждого участника проектной команды.
  • Дефектность продукта, bugs/KSLOC.
  • Качество архитектуры. Предлагаю читателям самим указать единицу измерения, в качестве упражнения.


Миф #6. Программисты анти-бюрократичны
Программисты – анти-идиотичны. Программисты сторонятся тех, кто усложняет их работу. Программисты самоорганизуются вокруг тех, кто облегчает их работу.

Миф #7. Программисты работают ради денег
Нет. Не ради денег. Но за деньги. Почувствуйте разницу.

Программист устроен просто. Он состоит из четырех компонентов: тело, сердце, разум и душа. Телу необходимы деньги и безопасность. Сердцу — любовь и признание. Разуму – развитие и самосовершенствование. Душе – самореализация.

Дайте все это вашим программистам, и вы получите максимальную эффективность. Что-то не найдете — уйдут к вашим конкурентам.

Источник: http://habrahabr.ru/post/192396/